ScalaCheck library comes with a wide variety of built-in generators, but let me show you how to combine them to make the library even more powerful.

## Map on generator

Generator comes with a method `map` which allows you to transform obtained data. Let’s create a generator which generates only positive, even integers:

``````val evenNumberGenerator: Gen[Int] = Gen.posNum[Int].map(_ * 2)
``````

In this case map accepts a function `Int => U`, since the generator on which the map is called returns `Int`. You can chain maps even further:

``````val oddNumberGenerator: Gen[Int] = evenNumberGenerator.map(_ + 1)
``````

## FlatMap on generator

Let’s suppose that you wold like to generate `Either[String, Int]`. We can use `flatMap` to handle this case. We will create `Right` if generated number is even and left if it’s odd:

``````  val leftOrRightFiftyFifty: Gen[Either[String, Int]] = Gen.posNum[Int].flatMap{ i =>
if(i % 2 == 0) Gen.posNum[Int].map(Right[String, Int])
else Gen.alphaLowerStr.map(Left[String, Int])
}
``````

FlatMap called on generator accepts a function `T => Gen[U]`. This allows you to combine generators further and further, leading to the generator which exactly suits your needs.

## Frequency generator

FlatMap is a very powerful tool, but requires a lot of boilerplate. What would happen if we wanted to obtain right 40% of time? What if we would have more and more possibilities? There is a nice built-in solution for this case. Take a look at `frequency` combinator:

``````val leftOrRight: Gen[Either[String, Int]] = Gen.frequency(
4 -> Gen.posNum[Int].map(Right[String, Int]),
6 -> Gen.alphaLowerStr.map(Left[String, Int])
)
``````

## Options here and options there

Option generators are well represented in ScalaCheck. If you want to always generate `Some[T]` you can use `Gen.some` like this:

``````val someOfIntGenerator: Gen[Option[Int]] = Gen.some(Gen.posNum[Int])
``````

In case you would like to have `Some` and `None` you can use `Gen.option`, to have both of the possibilities. It’s used in exactly the same way as `Gen.some`:

``````val optionalIntegerGenerator: Gen[Option[Int]] = Gen.option(Gen.posNum[Int])
``````

What is interesting `Gen.option` is implemented using `Gen.frequency`. Check it out here.

## Exclusive ranges

There might be a possibility that you want to generate a number from non overlapping ranges. Again you can use a nice built-in generator - `Gen.oneOf`. In this example we will generate numbers greater than 10 and smaller than 20 or bigger than 40 and smaller than 50. It’s as simple as this:

``````val oneOfRanges: Gen[Int] = Gen.oneOf(
Gen.chooseNum(10, 20),
Gen.chooseNum(40, 50)
)
``````

## Conclusion

Hopefully i managed to show you that ScalaCheck generators are easily combined, leading to code which can fit your exact needs.

Keep in mind that the examples I shown above are rather simple, but I hope you can already see usages which will fit your domain requirements.