我正在尝试按如下方式生成任意列表:
scala> def validPairs[T] = Arbitrary.arbitrary[List[(T, Option[T])]] suchThat(!_.isEmpty)
<console>:8: error: could not find implicit value for parameter a: org.scalacheck.Arbitrary[List[(T, Option[T])]]
def validPairs[T] = Arbitrary.arbitrary[List[(T, Option[T])]] suchThat(!_.isEmpty)
知道我在这里做错了吗?使用具体类型无需我定义隐式参数。
scala> def validPairsString = Arbitrary.arbitrary[List[(String, Option[String])]] suchThat(!_.isEmpty)
validPairsString: org.scalacheck.Gen[List[(String, Option[String])]]
这是使用scala 2.9.2和scalacheck 1.10.0
提前致谢。
答案 0 :(得分:2)
我自己遇到了这个问题,试图生成通用属性,以后可以为各种具体类型实例化。我发现OP的答案有点神秘,所以我认为提供更精细的答案会更好。我首先慢慢重复OP的回答。然后表明这同样适用于使用scalacheck编写属性。
关键问题是以下内容无法编译(我简化了OP给出的问题):
def validPair[T] = Arbitrary.arbitrary[(T,T)]
使用现代Scala编译器,您会收到不同的错误消息:
diverging implicit expansion for type org.scalacheck.Arbitrary[(T, T)]
starting with method arbTuple2 in trait ArbitraryArities
(这可以帮助谷歌今天解决这个问题的人)。
足以将类型参数绑定到任意位置(OP的答案在快速阅读时有点神秘):
def validPair[T :Arbitrary] = Arbitrary.arbitrary[(T,T)]
如果要定义通用属性,现在也需要这样做。这是幺半群的相关性公理的一个例子:
def associative[A :Arbitrary] (m: Monoid[A]) :Prop =
forAll ( (a1: A, a2: A, a3: A) => m.op(m.op(a1,a2), a3) == m.op(a1,m.op(a2,a3)) )
它产生类似的错误,没有A到任意的界限。我希望其他人开始用scalacheck编写他们的第一个通用属性会发现这很有用。
答案 1 :(得分:1)
在不同的列表中找到答案:def validPairs [T:Arbitrary] = ...(告诉它你将提供一种(可能是隐式的)生成T的方法。)