ScalaCheck:生成任意类型的任意函数
ScalaCheck: generate arbitrary functions with arbitrary types
我实现了以下功能:
/**
* 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)
我正在尝试使用 ScalaCheck 对其进行测试。我可以生成以下测试,编译并通过:
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)))
}
但我不知道它的语法,也不知道它是否可能。你能帮帮我吗?
scalatest website 对 forAll
有这样的说法:
An implicit Arbitrary
generator and Shrink
object needs to be supplied
for The forAll
method will pass each row of data to each parameter
type. ScalaCheck provides many implicit Arbitrary
generators for
common types such as Int
, String
, List[Float]
, etc., in its
org.scalacheck.Arbitrary
companion object. So long as you use types
for which ScalaCheck already provides implicit Arbitrary
generators,
you needn't worry about them. Same for Shrink
objects, which are
provided by ScalaCheck's org.scalacheck.Shrink
companion object. Most
often you can simply pass a property function to forAll
, and the
compiler will grab the implicit values provided by ScalaCheck.
所以很遗憾,您不能使用 forAll
来检查所有可能的类型,因为没有针对每种可能类型的隐式 Arbitrary
和 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 ...
我实现了以下功能:
/**
* 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)
我正在尝试使用 ScalaCheck 对其进行测试。我可以生成以下测试,编译并通过:
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)))
}
但我不知道它的语法,也不知道它是否可能。你能帮帮我吗?
scalatest website 对 forAll
有这样的说法:
An implicit
Arbitrary
generator andShrink
object needs to be supplied for TheforAll
method will pass each row of data to each parameter type. ScalaCheck provides many implicitArbitrary
generators for common types such asInt
,String
,List[Float]
, etc., in itsorg.scalacheck.Arbitrary
companion object. So long as you use types for which ScalaCheck already provides implicitArbitrary
generators, you needn't worry about them. Same forShrink
objects, which are provided by ScalaCheck'sorg.scalacheck.Shrink
companion object. Most often you can simply pass a property function toforAll
, and the compiler will grab the implicit values provided by ScalaCheck.
所以很遗憾,您不能使用 forAll
来检查所有可能的类型,因为没有针对每种可能类型的隐式 Arbitrary
和 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 ...