设为首页 加入收藏

TOP

Scalaz(9)- typeclass:checking instance abiding the laws(一)
2017-10-10 12:13:42 】 浏览:8890
Tags:Scalaz typeclass checking instance abiding the laws

  在前几篇关于Functor和Applilcative typeclass的讨论中我们自定义了一个类型Configure,Configure类型的定义是这样的:

 1 case class Configure[+A](get: A)  2 object Configure {  3     implicit val configFunctor = new Functor[Configure] {  4         def map[A,B](ca: Configure[A])(f: A => B): Configure[B] = Configure(f(ca.get))  5  }  6     implicit val configApplicative = new Applicative[Configure] {  7         def point[A](a: => A) = Configure(a)  8         def ap[A,B](ca: => Configure[A])(cfab: => Configure[A => B]): Configure[B] = cfab map {fab => fab(ca.get)}  9  } 10 }

通过定义了Configure类型的Functor和Applicative隐式实例(implicit instance),我们希望Configure类型既是一个Functor也是一个Applicative。那么怎么才能证明这个说法呢?我们只要证明Configure类型的实例能遵循它所代表的typeclass操作定律就行了。Scalaz为大部分typeclass提供了测试程序(scalacheck properties)。在scalaz/scalacheck-binding/src/main/scala/scalaz/scalacheck/scalazProperties.scala里我们可以发现有关functor scalacheck properties:

 1 object functor {  2     def identity[F[_], X](implicit F: Functor[F], afx: Arbitrary[F[X]], ef: Equal[F[X]]) =
 3  forAll(F.functorLaw.identity[X] _)  4 
 5     def composite[F[_], X, Y, Z](implicit F: Functor[F], af: Arbitrary[F[X]], axy: Arbitrary[(X => Y)],  6                                    ayz: Arbitrary[(Y => Z)], ef: Equal[F[Z]]) =
 7  forAll(F.functorLaw.composite[X, Y, Z] _)  8 
 9     def laws[F[_]](implicit F: Functor[F], af: Arbitrary[F[Int]], axy: Arbitrary[(Int => Int)], 10                    ef: Equal[F[Int]]) = new Properties("functor") { 11  include(invariantFunctor.laws[F]) 12       property("identity") = identity[F, Int] 13       property("composite") = composite[F, Int, Int, Int] 14  } 15   }

可以看到:functor.laws[F[_]]主要测试了identity, composite及invariantFunctor的properties。在scalaz/Functor.scala文件中定义了这几条定律:

 1  trait FunctorLaw extends InvariantFunctorLaw {  2     /** The identity function, lifted, is a no-op. */
 3     def identity[A](fa: F[A])(implicit FA: Equal[F[A]]): Boolean = FA.equal(map(fa)(x => x), fa)  4 
 5     /**  6  * A series of maps may be freely rewritten as a single map on a  7  * composed function.  8      */
 9     def composite[A, B, C](fa: F[A], f1: A => B, f2: B => C)(implicit FC: Equal[F[C]]): Boolean = FC.equal(map(map(fa)(f1))(f2), map(fa)(f2 compose f1)) 10  } 11

我们在下面试着对那个Configure类型进行Functor实例和Applicative实例的测试:

 1 import scalaz._  2 import Scalaz._  3 import shapeless._  4 import scalacheck.ScalazProperties._  5 import scalacheck.ScalazArbitrary._  6 import scalacheck.ScalaCheckBinding._  7 import org.scalacheck.{Gen, Arbitrary}  8 implicit def cofigEqual[A]: Equal[Configure[A]] = Equal.equalA  9                                                   //> cofigEqual: [A#2921073]=> scalaz#31.Equal#41646[Exercises#29.ex1#59011.Confi 10                                                   //| gure#2921067[A#2921073]]
11 implicit def configArbi[A](implicit a: Arbitrary[A]): Arbitrary[Configure[A]] =
12    a map { b => Configure(b) }                    //> configArbi: [A#2921076](implicit a#2921242: org#15.scalacheck#121951.Arbitra 13                                                   //| ry#122597[A#2921076])org#15.scalacheck#121951.Arbitrary#122597[Exercises#29. 14                                                   //| ex1#59011.Configure#2921067[A#2921076]]

除了需要的import外还必须定义Configure类型的Equal实例以及任意测试数据产生器(test data generator)configArbi[A]。我们先测试Functor属性:

1 functor.laws[Configure].check                     //> 
2 + functor.invariantFunctor.identity: OK, passed 100 tests. 3                                                   //| 
4 + functor.invariantFunctor.composite: OK, passed 100 tests. 5                                                   //| 
6 + functor.identity: OK, passed 100 tests. 7                                                   //| 
8 + functor.composite: OK, passed 100 tests.

成功通过Functor定律测试。

再看看Applicative的scala

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scalaz(8)- typeclass:Monoid.. 下一篇Scalaz(10)- Monad:就是一种..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目