【发布时间】:2018-04-15 11:20:42
【问题描述】:
我编写了一个 FsCheck 生成器,它生成随机 glob 语法模式(例如 a*c?)以及与该模式匹配的随机字符串(例如 abcd)。但是我的解决方案使用了一个可变变量,我对此感到很惭愧。看看:
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 转换为 text,但我不知道怎么做,因为我不明白 let! 是如何在幕后工作的(目前)。我正在考虑类似于以下内容:
let! text = pattern |> Seq.map toGen |> Seq.fold (?) (Gen.constant "")
我在正确的轨道上吗? fold 的累加器和种子应该是什么样的?
【问题讨论】:
标签: f# fscheck property-based-testing