ScalaCheck:生成具有任意类型的任意函数

ScalaCheck:生成具有任意类型的任意函数,scala,scalatest,scalacheck,Scala,Scalatest,Scalacheck,我已经实现了以下功能: /** * Returns a function h , which is the composition of the functions f and g. */ def compose[A, B, C](g: B => C, f: A => B): A => C = f.andThen(g) 我正试着用它来测试。我可以生成以下测试,这些测试可以编译并通过: import org.scalatest.prop.PropertyChecks i

我已经实现了以下功能:

/**
  * Returns a function h , which is the composition of the functions f and g.
  */
def compose[A, B, C](g: B => C, f: A => B): A => C = f.andThen(g)
我正试着用它来测试。我可以生成以下测试,这些测试可以编译并通过:

import org.scalatest.prop.PropertyChecks
import org.scalatest.{FlatSpec, Matchers}

class ComposeSpec extends FlatSpec with Matchers with PropertyChecks {

  "Compose" should "return a function h , which is the composition of the 
functions f and g" in {

    forAll { (a: Int, g: Int => Int, f: Int => Int) =>
      compose(g, f)(a) should be(g(f(a)))
    }

    forAll { (a: String, g: Double => Int, f: String => Double) =>
      compose(g, f)(a) should be(g(f(a)))
    }
  }
}
但是,正如您所看到的,我正在生成具有定义类型的任意函数,并且还将参数
a
的类型与函数
f
的输入类型相匹配。我想做的事情如下:

forAll { (a: A, g: B => C, f: A => B) =>
  compose(g, f)(a) should be(g(f(a)))
}
但我不知道它的语法,也不知道它是否可能。你能帮帮我吗?

关于所有的

需要提供隐式
任意
生成器和
收缩
对象 对于
forAll
方法,将每行数据传递给每个参数 类型。ScalaCheck为 its中的常见类型,如
Int
String
List[Float]
org.scalacheck.arbitral
伴随对象。只要你使用类型 ScalaCheck已经为其提供了隐式
任意
生成器,
你不必为他们担心。同样适用于
收缩
对象,它们是 由ScalaCheck的
org.ScalaCheck.Shrink
伴生对象提供。最 通常,您只需将属性函数传递给所有
,然后 编译器将获取ScalaCheck提供的隐式值

不幸的是,您不能使用
forAll
来检查每一种可能的类型,因为对于每一种可能的类型,都没有隐式的
arbitral
Shrink
对象。似乎很难生成任何类型的任意对象

你能做的最好的事情是:

def checkComposeForAll[A : Arbitrary : Shrink, B : Arbitrary : Shrink, C : Arbitrary : Shrink]() = {
  forAll { (a: A, g: B => C, f: A => B) =>
    compose(g, f)(a) should be(g(f(a)))
  }
}

checkComposeForAll[Int, Int, Int]()
checkComposeForAll[String, String, String]()
checkComposeForAll[List[Int], Double, Int]()
// ... etc, check a bunch of types ...