{"rsdb":{"rid":"179826","subhead":"","postdate":"0","aid":"130443","fid":"90","uid":"1","topic":"1","content":"
\n

  \u5728\u524d\u51e0\u7bc7\u5173\u4e8eFunctor\u548cApplilcative typeclass\u7684\u8ba8\u8bba\u4e2d\u6211\u4eec\u81ea\u5b9a\u4e49\u4e86\u4e00\u4e2a\u7c7b\u578bConfigure\uff0cConfigure\u7c7b\u578b\u7684\u5b9a\u4e49\u662f\u8fd9\u6837\u7684\uff1a<\/span><\/p> \n

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

\u901a\u8fc7\u5b9a\u4e49\u4e86Configure\u7c7b\u578b\u7684Functor\u548cApplicative\u9690\u5f0f\u5b9e\u4f8b\uff08implicit instance\uff09\uff0c\u6211\u4eec\u5e0c\u671bConfigure\u7c7b\u578b\u65e2\u662f\u4e00\u4e2aFunctor\u4e5f\u662f\u4e00\u4e2aApplicative\u3002\u90a3\u4e48\u600e\u4e48\u624d\u80fd\u8bc1\u660e\u8fd9\u4e2a\u8bf4\u6cd5\u5462\uff1f\u6211\u4eec\u53ea\u8981\u8bc1\u660eConfigure\u7c7b\u578b\u7684\u5b9e\u4f8b\u80fd\u9075\u5faa\u5b83\u6240\u4ee3\u8868\u7684typeclass\u64cd\u4f5c\u5b9a\u5f8b\u5c31\u884c\u4e86\u3002Scalaz\u4e3a\u5927\u90e8\u5206typeclass\u63d0\u4f9b\u4e86\u6d4b\u8bd5\u7a0b\u5e8f\uff08scalacheck properties\uff09\u3002\u5728scalaz\/scalacheck-binding\/src\/main\/scala\/scalaz\/scalacheck\/scalazProperties.scala\u91cc\u6211\u4eec\u53ef\u4ee5\u53d1\u73b0\u6709\u5173functor scalacheck properties:<\/span><\/p> \n

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

\u53ef\u4ee5\u770b\u5230\uff1afunctor.laws[F[_]]\u4e3b\u8981\u6d4b\u8bd5\u4e86identity, composite\u53cainvariantFunctor\u7684properties\u3002\u5728scalaz\/Functor.scala\u6587\u4ef6\u4e2d\u5b9a\u4e49\u4e86\u8fd9\u51e0\u6761\u5b9a\u5f8b\uff1a<\/span><\/p> \n

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

\u6211\u4eec\u5728\u4e0b\u9762\u8bd5\u7740\u5bf9\u90a3\u4e2aConfigure\u7c7b\u578b\u8fdb\u884cFunctor\u5b9e\u4f8b\u548cApplicative\u5b9e\u4f8b\u7684\u6d4b\u8bd5\uff1a<\/span><\/p> \n

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

\u9664\u4e86\u9700\u8981\u7684import\u5916\u8fd8\u5fc5\u987b\u5b9a\u4e49Configure\u7c7b\u578b\u7684Equal\u5b9e\u4f8b\u4ee5\u53ca\u4efb\u610f\u6d4b\u8bd5\u6570\u636e\u4ea7\u751f\u5668\uff08test data generator\uff09configArbi[A]\u3002\u6211\u4eec\u5148\u6d4b\u8bd5Functor\u5c5e\u6027\uff1a<\/span><\/p> \n

\n
1<\/span> functor.laws[Configure].check                     \/\/<\/span>> <\/span>\r\n2<\/span> + functor.invariantFunctor.identity: OK, passed 100<\/span> tests. <\/span>3<\/span>                                                   \/\/<\/span>| <\/span>\r\n4<\/span> + functor.invariantFunctor.composite: OK, passed 100<\/span> tests. <\/span>5<\/span>                                                   \/\/<\/span>| <\/span>\r\n6<\/span> + functor.identity: OK, passed 100<\/span> tests. <\/span>7<\/span>                                                   \/\/<\/span>| <\/span>\r\n8<\/span> + functor.composite: OK, passed 100<\/span> tests.<\/span><\/pre> \n <\/div> \n 

\u6210\u529f\u901a\u8fc7Functor\u5b9a\u5f8b\u6d4b\u8bd5\u3002<\/span><\/p> \n

\u518d\u770b\u770bApplicative\u7684scala","orderid":"0","title":"Scalaz\uff089\uff09\uff0d typeclass\uff1achecking instance abiding the laws(\u4e00)","smalltitle":"","mid":"0","fname":"Scala","special_id":"0","bak_id":"0","info":"0","hits":"8897","pages":"2","comments":"0","posttime":"2017-10-10 12:13:42","list":"1507608822","username":"admin","author":"","copyfrom":"","copyfromurl":"","titlecolor":"","fonttype":"0","titleicon":"0","picurl":"https:\/\/www.cppentry.com\/upload_files\/","ispic":"0","yz":"1","yzer":"","yztime":"0","levels":"0","levelstime":"0","keywords":"Scalaz<\/A> typeclass<\/A> checking<\/A> instance<\/A> abiding<\/A> the<\/A> laws<\/A>","jumpurl":"","iframeurl":"","style":"","template":"a:3:{s:4:\"head\";s:0:\"\";s:4:\"foot\";s:0:\"\";s:8:\"bencandy\";s:0:\"\";}","target":"0","ip":"113.108.110.181","lastfid":"0","money":"0","buyuser":"","passwd":"","allowdown":"","allowview":"","editer":"","edittime":"0","begintime":"0","endtime":"0","description":"Scalaz\uff089\uff09\uff0d typeclass\uff1achecking instance abiding the laws","lastview":"1713912945","digg_num":"8793","digg_time":"0","forbidcomment":"0","ifvote":"0","heart":"","htmlname":"","city_id":"0"},"page":"1"}