【问题标题】:Scalacheck arbitrary with genericsScalacheck 任意与泛型
【发布时间】:2013-04-30 15:43:17
【问题描述】:

我正在尝试生成如下任意列表:

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

提前致谢。

【问题讨论】:

  • 在另一个列表中找到答案:def validPairs[T : Arbitrary] = ...(告诉它您将提供一种(可能是隐含的)生成 T 的方式。)

标签: scala scalacheck


【解决方案1】:

我自己也遇到过这个问题,试图生成通用属性,以后可以为各种具体类型实例化。我发现 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 到 Arbitrary 的限制,它会产生类似的错误。我希望其他开始使用 scalacheck 编写他们的第一个通用属性的人会发现这很有用。

【讨论】:

    【解决方案2】:

    在另一个列表中找到答案:def validPairs[T : Arbitrary] = ...(告诉它您将提供一种(可能是隐式的)生成 T 的方式。)

    【讨论】:

      猜你喜欢
      • 2018-10-28
      • 1970-01-01
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      相关资源
      最近更新 更多