A simpler Arbitrary for the Diamond kata by Mark Seemann
There's a simple way to make FsCheck generate letters in a particular range.
In my post about the Diamond kata with FsCheck, I changed the way FsCheck generates char values, using this custom Arbitrary (essentially a random value generator):
type Letters = static member Char() = Arb.Default.Char() |> Arb.filter (fun c -> 'A' <= c && c <= 'Z')
This uses the default, built-in Arbitrary for char values, but filters its values so that most of them are thrown away, and only the letters 'A'-'Z' are left. This works, but isn't particularly efficient. Why generate a lot of values only to throw them away?
It's also possible to instruct FsCheck to generate values from a particular set of valid values, which seems like an appropriate action to take here:
type Letters = static member Char() = Gen.elements ['A' .. 'Z'] |> Arb.fromGen
Instead of using
Arb.Default.Char() and filtering the values generated by it, this implementation uses
Gen.elements to create a Generator of the values 'A'-'Z', and then an Arbitrary from that Generator.
Much simpler, but now it's also clear that this custom Arbitrary will be used to generate 100 test cases (for each property) from a set of 26 values; that doesn't seem right...