Skip to content

Instantly share code, notes, and snippets.

@giacomociti
Created September 29, 2015 13:03
Show Gist options
  • Save giacomociti/dca67686124d05870e30 to your computer and use it in GitHub Desktop.
Save giacomociti/dca67686124d05870e30 to your computer and use it in GitHub Desktop.
fsCheck sized generator from fare regex-based generator
#r @"..\packages\Fare.1.0.0\lib\net35\Fare.dll"
#r @"..\packages\FsCheck.2.0.4\lib\net45\FsCheck.dll"
open Fare
open FsCheck
open System.Collections.Generic
// partial and naive implementation of a generator attempting to honor the size
let generator pattern =
// pre-compute a certain amount of values and group them by size
let xeger = Xeger pattern
let dict = Dictionary<int, Queue<string>>()
[for i in 1..1000 -> xeger.Generate()]
|> Seq.groupBy String.length // use length for the size
|> Seq.iter (fun (len, vals) -> dict.Add(len, vals |> Queue))
dict |> Seq.iter (fun x -> printfn "size %i: %i items" x.Key x.Value.Count)
// now build a sized generator as a lookup on the previously computed values
fun size ->
gen { return
match dict.TryGetValue size with
| true, vals when vals.Count > 0 -> vals.Dequeue()
// fallback to generating new values ignoring the size,
// but a better strategy may be developed here,
// for example looking for values of similar size.
// Another improvement needed is to somehow 'refill' dict
// once in a while, otherwise it soon gets empty
| _ ->
printfn "missing items of size %i" size
xeger.Generate() }
|> Gen.sized
let example = generator "[abc]+"
for size in 1..10 do
example
|> Gen.sample size 5
|> List.iter (printfn "size %i: %s" size)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment