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.

In this post I’ll be generating random strings from randomly selected characters. I will also describe a way of customizing the whole creation process.

The following generators are required for this:

Given the above, a generator for strings can be written as:

/// <summary>
/// Generates a random string.
/// </summary>
let string =
    Gen.char
    |> Gen.list
    |> Gen.map (List.toArray >> System.String)

Here are some sample strings:

> Gen.string |> Gen.generate;;
val it : String = "lof5ºÛ"

> Gen.string |> Gen.generate;;
val it : String = "'fv*™ì UÇ"

> Gen.string |> Gen.generate;;
val it : String = "Ðê

Customizations

Generarting upper-case strings

let upperCase = Gen.choose (65,  90) |> Gen.map Operators.char

val upperCase : Gen<char>


let customString g =
    g
    |> Gen.list
    |> Gen.map (List.toArray >> System.String)

val customString : g:Gen<char> -> Gen<String>

Sample output:

> upperCase |> customString |> Gen.generate;;
val it : String = "DGVHAYFAWIHQBOD"

> upperCase |> customString |> Gen.generate;;
val it : String = "HEDDZYBATTYL"

> upperCase |> customString |> Gen.generate;;
val it : String = "XLYJSMEYYZXN"

Generating lower-case strings

let lowerCase = Gen.choose (97, 122) |> Gen.map Operators.char

val lowerCase : Gen<char>


let customString g =
    g
    |> Gen.list
    |> Gen.map (List.toArray >> System.String)

val customString : g:Gen<char> -> Gen<String>

Sample output:

> lowerCase |> customString |> Gen.generate;;
val it : String = "qsnj"

> lowerCase |> customString |> Gen.generate;;
val it : String = "cltfvqckqxeirmuqvjn"

> lowerCase |> customString |> Gen.generate;;
val it : String = "wzwfojfjlrjglu"