有没有办法在FsCheck中生成一个字符串,只从每个字符串列表中选择一个项目然后连接结果?
我只是完全陷入困境,似乎无法弄明白.我查看了文档和github repo中的类似内容.而且我已经从FSharpForFunAndProfit完成了对FsCheck的大部分阅读.
这就像我想的那样:
let rand = System.Random()
let randInt max = rand.Next(0, max)
let selectLetter (string: string) =
let whichLettersIndex = String.length string |> randInt
string.Substring(whichLettersIndex, 1)
let generateOddlySpelledWord listOfStrings =
List.map selectLetter listOfStrings
|> String.concat ""
let usingGenerateOddlySpelledWord =
generateOddlySpelledWord ["zZ"; "oO0Ò"; "eEê"]
Run Code Online (Sandbox Code Playgroud)
这应该产生类似"Z0ê"或"zÒE"的东西.
这样做你想要的吗?
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
Run Code Online (Sandbox Code Playgroud)
特别测试:
open FsCheck.Xunit
[<Property(Arbitrary = [| typeof<OddlySpelledWords> |])>]
let test (s : string) =
printfn "%s" s
Run Code Online (Sandbox Code Playgroud)
输出(截断):
z0ê
ZÒe
ZOe
zoê
ZÒe
zoê
Z0e
zoê
z0ê
ZOe
zÒê
z0E
zoe
Run Code Online (Sandbox Code Playgroud)
说明
该createGenerators函数具有类型seq string -> Gen<char> list,并且它Gen使用每个字符串创建一个Gen.elements,因为字符串也是一个char seq; Gen.elements创建一个将从每个字符串中Gen选择其中一个char值.
然后它用于Gen.sequence转换Gen<char> list为a Gen <char list>,然后从那里映射.
顺便说一下,你也可以内联createGenerators:
type OddlySpelledWords =
static member String() =
["zZ"; "oO0Ò"; "eEê"]
|> List.map Gen.elements
|> Gen.sequence
|> Gen.map (List.map string >> String.concat "")
|> Arb.fromGen
Run Code Online (Sandbox Code Playgroud)