我想生成一个与ScalaCheck
中的生成器列表对应的整数列表。
import org.scalacheck._
import Arbitrary.arbitrary
val smallInt = Gen.choose(0,10)
val bigInt = Gen.choose(1000, 1000000)
val zeroOrOneInt = Gen.choose(0, 1)
val smallEvenInt = smallInt suchThat (_ % 2 == 0)
val gens = List(smallInt, bigInt, zeroOrOneInt, smallEvenInt)
//val listGen: Gen[Int] = ??
//println(listGen.sample) //should print something like List(2, 2000, 0, 6)
对于给定的gens
,我想创建一个生成器listGen
,其有效样本可以是List(2, 2000, 0, 6)
。
这是我第一次尝试使用元组。
val gensTuple = (smallInt, bigInt, zeroOrOneInt, smallEvenInt)
val tupleGen = for {
a <- gensTuple._1
b <- gensTuple._2
c <- gensTuple._3
d <- gensTuple._4
} yield (a, b, c, d)
println(tupleGen.sample) // prints Some((1,318091,0,6))
这有效,但我不想使用元组,因为生成器列表(gens
)是动态创建的
并且列表的大小不固定。有没有办法用Lists做到这一点?
我希望在scalacheck listGen
属性检查中使用列表生成器(forAll
)。
这看起来像玩具问题,但确实如此 我能做的最好的事情是创建一个独立的片段来重现我的实际问题 面对。
答案 0 :(得分:10)
如何使用Gen.sequence
方法?它将Iterable[Gen[T]]
转换为Gen[C[T]]
,其中C
可以是List
:
def sequence[C[_],T](gs: Iterable[Gen[T]])(implicit b: Buildable[T,C]): Gen[C[T]] =
...
答案 1 :(得分:1)
编辑:请忽略,这不回答提问者的问题
我还不能对帖子发表评论,所以我不得不在这里猜测。我假设函数'sample'适用于生成器
你不能做的任何理由:
gens map (t=>t.sample)
答案 2 :(得分:0)
要获得更理论的答案:您想要的方法是traverse
,它等同于sequence compose map
,尽管它可能更有效。它具有一般形式:
def traverse[C[_]: Traverse, F[_]: Applicative, A, B](f: A => F[B], t: C[A]): F[C[B]]
它的行为类似于map
,但允许您在遍历期间携带一些额外的Applicative
结构,并在此过程中对其进行排序。
答案 3 :(得分:0)
只需使用Gen.sequence
,但请注意,如果您没有完全参数化java.util.ArrayList[T]
,它会尝试返回def genIntList(): Gen[List[Int]] = {
val gens = List(Gen.chooseNum(1, 2), Gen.chooseNum(3, 4))
Gen.sequence[List[Int], Int](gens)
}
println(genIntList.sample.get) // prints: List(1,4)
。
完整的工作示例:
{{1}}