8

のジェネレーターのリストに対応する整数のリストを生成したいと考えています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ジェネレーターを作成したいと思います。これがタプルを使用した最初の試みです。listGenList(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これは機能しますが、generators( ) のリストが動的に作成され、リストのサイズが固定されていないため、タプルを使用したくありません。リストでそれを行う方法はありますか?

listGenscalacheck のforAllプロパティ チェックでlist( ) のジェネレータを使用したい。

これはおもちゃの問題のように見えますが、これは私が直面している実際の問題を再現するスタンドアロンのスニペットを作成するためにできる最善の方法です。

4

4 に答える 4

14

Gen.sequenceメソッドを使ってみてはどうですか?をに変換Iterable[Gen[T]]します。Gen[C[T]]CList

  def sequence[C[_],T](gs: Iterable[Gen[T]])(implicit b: Buildable[T,C]): Gen[C[T]] = 
     ...
于 2012-11-25T10:56:37.153 に答える
3

を使用するだけですが、完全にパラメータ化しないとGen.sequencea を返そうとするので注意してください(バグ)。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)
于 2017-01-05T04:09:02.320 に答える
1

編集:無視してください、これは質問者の質問に答えません


まだ投稿にコメントできないので、ここで推測する必要があります。関数'sample'がジェネレーターに適用されると思います

あなたができない理由:

gens map (t=>t.sample)
于 2012-11-25T10:16:10.520 に答える
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の構造を持ち運ぶことができ、途中で順序付けできます。

于 2012-12-20T20:11:20.843 に答える