パターンに一致するランダムな文字列(例えば、abcd
)とともにランダムなグロブ構文パターン(例えば、a*c?
)を生成するFsCheckジェネレータを書きました。しかし、私の解決策は可変変数を使用しており、私はむしろそれを恥じています。見て:text
が可変であることと、その値がループ内に蓄積された方法をFsCheckジェネレータのリストを単一の値に累積する方法は?
open FsCheck
type TestData = {Pattern: string; Text: string}
let stringFrom alphabet =
alphabet |> Gen.elements |> Gen.listOf |> Gen.map (List.map string >> List.fold (+) "")
let singleCharStringFrom alphabet =
alphabet |> Gen.elements |> Gen.map string
let matchingTextAndPatternCombo = gen {
let toGen = function
| '*' -> stringFrom ['a'..'f']
| '?' -> singleCharStringFrom ['a'..'f']
| c -> c |> string |> Gen.constant
let! pattern = stringFrom (['a'..'c']@['?'; '*'])
let mutable text = ""
for gen in Seq.map toGen pattern do
let! textPart = gen
text <- text + textPart
return {Pattern = pattern; Text = text}
}
は注意してください。
私の根性はtext
に発電機をfold
する方法がなければならないことを教えて、私は(まだ)ボンネットの下にどのようlet!
作品を理解していないので、私は、どのように理解することはできません。私は次のようなものを考えていました:
let! text = pattern |> Seq.map toGen |> Seq.fold (?) (Gen.constant "")
私は正しい道にいますか? fold
のアキュムレータとシードはどのように見えるのですか?
私は、次のアキュムレータを思い付いた: '楽しいcurrGenネクストジェン - > currGen >> = - |'(> NextGenの楽しいテキスト> Gen.map((+)テキスト))。しかし、 'Gen.sequence'によるあなたのアプローチは、もっと読みやすく、慣用的です。ありがとう! –