Search code examples
scalascalacheck

Scalacheck: Generate list corresponding to list of generators


I want to generate a list of integers corresponding to a list of generators in 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)

For the given gens, I would like to create a generator listGen whose valid sample can be List(2, 2000, 0, 6). Here is my first attempt using tuples.

    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))

This works, but I don't want to use tuples since the list of generators(gens) is created dynamically and the size of the list is not fixed. Is there a way to do it with Lists?

I want the use the generator of the list(listGen) in scalacheck forAll property checking.

This looks like a toy problem but this is the best I could do to create a standalone snippet reproducing the actual issue I am facing.


Solution

  • How about using the Gen.sequence method? It transforms an Iterable[Gen[T]] into a Gen[C[T]], where C can be List:

      def sequence[C[_],T](gs: Iterable[Gen[T]])(implicit b: Buildable[T,C]): Gen[C[T]] = 
         ...