Does it do what you want?
open FsCheck let createGenerators (l : string seq) = l |> Seq.map Gen.elements |> Seq.toList type OddlySpelledWords = static member String() = ["zZ"; "oO0Ò"; "eEê"] |> createGenerators |> Gen.sequence |> Gen.map (List.map string >> String.concat "") |> Arb.fromGen
Ad-hoc test:
open FsCheck.Xunit [<Property(Arbitrary = [| typeof<OddlySpelledWords> |])>] let test (s : string) = printfn "%s" s
Output (Truncated):
z0ê ZÒe ZOe zoê ZÒe zoê Z0e zoê z0ê ZOe zÒê z0E zoe
Explanation
The createGenerators function is of type seq string -> Gen<char> list , and it creates Gen from each row using Gen.elements , because the string is also char seq ; Gen.elements creates a Gen that selects one of these char values from each row.
Then it uses Gen.sequence to convert the Gen<char> list to Gen <char list> , and then displays from there.
By the way, you can also enable createGenerators :
type OddlySpelledWords = static member String() = ["zZ"; "oO0Ò"; "eEê"] |> List.map Gen.elements |> Gen.sequence |> Gen.map (List.map string >> String.concat "") |> Arb.fromGen
source share