Scalaz(9)- typeclass:checking instance abiding the laws

2024-04-09 05:08

本文主要是介绍Scalaz(9)- typeclass:checking instance abiding the laws,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

case class Configure[+A](get: A)
object Configure {implicit val configFunctor = new Functor[Configure] {def map[A,B](ca: Configure[A])(f: A => B): Configure[B] = Configure(f(ca.get))}implicit val configApplicative = new Applicative[Configure] {def point[A](a: => A) = Configure(a)def ap[A,B](ca: => Configure[A])(cfab: => Configure[A => B]): Configure[B] = cfab map {fab => fab(ca.get)}}
}

通过定义了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:

 object functor {def identity[F[_], X](implicit F: Functor[F], afx: Arbitrary[F[X]], ef: Equal[F[X]]) =forAll(F.functorLaw.identity[X] _)def composite[F[_], X, Y, Z](implicit F: Functor[F], af: Arbitrary[F[X]], axy: Arbitrary[(X => Y)],ayz: Arbitrary[(Y => Z)], ef: Equal[F[Z]]) =forAll(F.functorLaw.composite[X, Y, Z] _)def laws[F[_]](implicit F: Functor[F], af: Arbitrary[F[Int]], axy: Arbitrary[(Int => Int)],ef: Equal[F[Int]]) = new Properties("functor") {include(invariantFunctor.laws[F])property("identity") = identity[F, Int]property("composite") = composite[F, Int, Int, Int]}}

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

 trait FunctorLaw extends InvariantFunctorLaw {/** The identity function, lifted, is a no-op. */def identity[A](fa: F[A])(implicit FA: Equal[F[A]]): Boolean = FA.equal(map(fa)(x => x), fa)/*** A series of maps may be freely rewritten as a single map on a* composed function.*/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))}。。。

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

import scalaz._
import Scalaz._
import shapeless._
import scalacheck.ScalazProperties._
import scalacheck.ScalazArbitrary._
import scalacheck.ScalaCheckBinding._
import org.scalacheck.{Gen, Arbitrary}
implicit def cofigEqual[A]: Equal[Configure[A]] = Equal.equalA//> cofigEqual: [A#2921073]=> scalaz#31.Equal#41646[Exercises#29.ex1#59011.Confi//| gure#2921067[A#2921073]]
implicit def configArbi[A](implicit a: Arbitrary[A]): Arbitrary[Configure[A]] =a map { b => Configure(b) }                    //> configArbi: [A#2921076](implicit a#2921242: org#15.scalacheck#121951.Arbitra//| ry#122597[A#2921076])org#15.scalacheck#121951.Arbitrary#122597[Exercises#29.//| ex1#59011.Configure#2921067[A#2921076]]

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

functor.laws[Configure].check                     //> 
+ functor.invariantFunctor.identity: OK, passed 100 tests.//| 
+ functor.invariantFunctor.composite: OK, passed 100 tests.//| 
+ functor.identity: OK, passed 100 tests.//| 
+ functor.composite: OK, passed 100 tests.

成功通过Functor定律测试。

再看看Applicative的scalacheck property:scalaz/scalacheck/scalazProperties.scala

 object applicative {def identity[F[_], X](implicit f: Applicative[F], afx: Arbitrary[F[X]], ef: Equal[F[X]]) =forAll(f.applicativeLaw.identityAp[X] _)def homomorphism[F[_], X, Y](implicit ap: Applicative[F], ax: Arbitrary[X], af: Arbitrary[X => Y], e: Equal[F[Y]]) =forAll(ap.applicativeLaw.homomorphism[X, Y] _)def interchange[F[_], X, Y](implicit ap: Applicative[F], ax: Arbitrary[X], afx: Arbitrary[F[X => Y]], e: Equal[F[Y]]) =forAll(ap.applicativeLaw.interchange[X, Y] _)def mapApConsistency[F[_], X, Y](implicit ap: Applicative[F], ax: Arbitrary[F[X]], afx: Arbitrary[X => Y], e: Equal[F[Y]]) =forAll(ap.applicativeLaw.mapLikeDerived[X, Y] _)def laws[F[_]](implicit F: Applicative[F], af: Arbitrary[F[Int]],aff: Arbitrary[F[Int => Int]], e: Equal[F[Int]]) = new Properties("applicative") {include(ScalazProperties.apply.laws[F])property("identity") = applicative.identity[F, Int]property("homomorphism") = applicative.homomorphism[F, Int, Int]property("interchange") = applicative.interchange[F, Int, Int]property("map consistent with ap") = applicative.mapApConsistency[F, Int, Int]}}

applicative.laws定义了4个测试Property再加上apply的测试property。这些定律(laws)在scalaz/Applicative.scala里定义了:

  trait ApplicativeLaw extends ApplyLaw {/** `point(identity)` is a no-op. */def identityAp[A](fa: F[A])(implicit FA: Equal[F[A]]): Boolean =FA.equal(ap(fa)(point((a: A) => a)), fa)/** `point` distributes over function applications. */def homomorphism[A, B](ab: A => B, a: A)(implicit FB: Equal[F[B]]): Boolean =FB.equal(ap(point(a))(point(ab)), point(ab(a)))/** `point` is a left and right identity, F-wise. */def interchange[A, B](f: F[A => B], a: A)(implicit FB: Equal[F[B]]): Boolean =FB.equal(ap(point(a))(f), ap(f)(point((f: A => B) => f(a))))/** `map` is like the one derived from `point` and `ap`. */def mapLikeDerived[A, B](f: A => B, fa: F[A])(implicit FB: Equal[F[B]]): Boolean =FB.equal(map(fa)(f), ap(fa)(point(f)))}

再测试一下Configure类型是否也遵循Applicative定律:

applicative.laws[Configure].check                 //> 
+ applicative.apply.functor.invariantFunctor.identity: OK, passed 100 tests//| //|   .//| 
+ applicative.apply.functor.invariantFunctor.composite: OK, passed 100 test//| //|   s.//| 
+ applicative.apply.functor.identity: OK, passed 100 tests.//| 
+ applicative.apply.functor.composite: OK, passed 100 tests.//| 
+ applicative.apply.composition: OK, passed 100 tests.//| 
+ applicative.identity: OK, passed 100 tests.//| 
+ applicative.homomorphism: OK, passed 100 tests.//| 
+ applicative.interchange: OK, passed 100 tests.//| 
+ applicative.map consistent with ap: OK, passed 100 tests.

成功通过了Applicative定律测试。现在我们可以说Configure类型既是Functor也是Applicative。






这篇关于Scalaz(9)- typeclass:checking instance abiding the laws的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/887247

相关文章

OpenStack实例操作选项解释:启动和停止instance实例

关于启动和停止OpenStack实例 如果你想要启动和停止OpenStack实例时,有四种方法可以考虑。 管理员可以暂停、挂起、搁置、停止OpenStack 的计算实例。但是这些方法之间有什么不同之处? 目录 关于启动和停止OpenStack实例1.暂停和取消暂停实例2.挂起和恢复实例3.搁置(废弃)实例和取消废弃实例4.停止(删除)实例 1.暂停和取消暂停实例

Error: label vector and instance matrix must be double的解决方法

在使用uci下载的数据时,建模时出现这个错误的解决方法 首先现在UCI上面下载数据 然后右键另存为就行了。这样我们就从UCI里面下载到了训练数据 在matlab 点 导入数据,数据类型要记得选第二个, 如果选择最后一个table就会出现这个问题 最后附上代码 %%之前先import wine.date IMPORTED DATA 设为Numeric Matrix (数值矩

【Unity3D】【UI】Cannot restructure Prefab instance.

触发原因未知,猜测是策划把别的预设A挪了一个改了个名字成了预设B。想要改动预设B中的组件产生了一下报错。 Cannot restructure Prefab instance. Children of a Prefab instance cannot be deleted or moved,and components cannot be reordered. You can open th

Error when checking model target: expected activation_2 to have shape (None, 10) but got array with

我遇到了这个问题,因为我在用reshape层后,忘了改我的GT label的尺寸。 reshape最终的输出是10长度的,但是标签用的还是1长度的 就是(0,0,1,0,0,0,0,...)与3的不匹配

java4Android(23):equals 的使用方法 instance 操作符【==与equals方法的区别】

1:所有类都继承了equals方法 2:“==”表示两端的引用所指是堆内存中的同一对象 3:equals用来比较对象的内容是否相同。什么是对象的内容相同? 3.1 对象的类型相同 3.2 对象的成员变量值相同 4:a instanceof User 判断对象a是否是User类型

No enclosing instance of type Outer is accessible. Must qualify the allocation with an enclosing ins

之前看内部类的时候没发现这个问题,今天写代码的时候遇到,写个最简单的例子: 下面这一段代码 红色的部分就是编译报错: No enclosing instance of type Outer is accessible. Must qualify the allocation with an enclosing instance of type Outer (e.g. x.new

URP简洁的instance的写法

材质还是要开启enable instance,这是上一次的写法 https://dbbh666.blog.csdn.net/article/details/136644181 最近发现更适合我个人的习惯的写法 就是代码控制这个整个过程 C#代码是这样的,获取一个mesh,获取每个mesh的transform,核心就完了,我这里是场景里的cube的mesh取来直接使用 using UnityEng

【Pytorch】Linear 层,举例:相机参数和Instance Feaure通过Linear层生成Group Weights

背景 看论文看到这个pipeline,对于相机参数和Instance Fature 的融合有点兴趣,研究如下: Linear 层 Linear 层是最基本的神经网络层之一,也称为全连接层。它将输入与每个输出神经元完全连接。每个连接都有一个权重和一个偏置。 示例代码 import torchimport torch.nn as nn# 定义一个简单的全连接网络,包含两个Linear层

No enclosing instance of type test is accessible. Must qualify the allocation with an enclosing inst

今日遇到一个报错如下: No enclosing instance of type test is accessible. Must qualify the allocation with an enclosing instance of type test (e.g. x.new A() where x is an instance of test). 问题出现的原因是: