# Write you some QuickCheck - Generating random bytes

10 Feb 2016

This post is part of a series of posts on implementing a minimal version of QuickCheck from scratch. The source code is available on GitHub.

We already have a function that runs a generator `Gen<'a>`

and returns random test data of type `'a`

.

```
val generate : Gen<'a> -> 'a
```

Now, in order to be able to generate random bytes, we need a couple of generators:

- a generator that picks numbers from a given range (in this case [0..255])
- a generator that applies a function (in this case
`Operators.byte<^T>`

) to an existing generator

Porting Gen’s `choose`

```
/// <summary>
/// Generates a random element in the given inclusive range, uniformly
/// distributed in the closed interval [lo,hi].
/// </summary>
/// <param name="lo">The lower bound.</param>
/// <param name="hi">The upper bound.</param>
let choose (lo, hi) = Gen(fun n r -> r) |> Gen.map (Random.range (lo, hi) >> fst)
```

Porting Gen’s `map`

, `bind`

, and `return`

^{1} since `choose`

depends on them

```
/// <summary>
/// Sequentially compose two actions, passing any value produced by the first
/// as an argument to the second.
/// </summary>
/// <param name="f">
/// The action that produces a value to be passed as argument to the generator.
/// </param>
let bind (Gen m) f =
Gen(fun n r ->
let (r1, r2) = r |> Random.split
let (Gen m') = f (m n r1)
m' n r2)
/// <summary>
/// Injects a value into a generator.
/// </summary>
/// <param name="a">The value to inject into a generator.</param>
let init a = Gen(fun n r -> a)
/// <summary>
/// Returns a new generator obtained by applying a function to an existing
/// generator.
/// </summary>
/// <param name="f">The function to apply to an existing generator.</param>
/// <param name="m">The existing generator.</param>
let map f m =
bind m (fun m' ->
init (f m'))
```

All the pieces are now in place, and so a byte generator can be written as:

```
let byte = Gen.choose (0, 255) |> Gen.map Operators.byte
val byte : Gen<byte>
```

Finally, here are some sample bytes:

```
> Gen.byte |> Gen.generate;;
val it : byte = 125uy
> Gen.byte |> Gen.generate;;
val it : byte = 201uy
> Gen.byte |> Gen.generate;;
val it : byte = 3uy
```

## Wish to comment?

You can discuss this post on Twitter or elsewhere with a permalink.
I'm on Twitter as @nikosbaxevanis.
I check my Twitter mentions pretty regularly. That's the best way to contact me.