f# - FsCheck 满足谓词的列表的自定义生成器
问题描述
对于给定的谓词pred : 'a list -> bool
和生成器gen : Gen<'a>
,请考虑以下满足谓词的格式良好列表的生成器:
let wellFormedList pred gen =
Gen.ofList gen
|> Gen.filter pred
如FsCheck 手册中所述,谓词应该很有可能适用于随机列表。不幸的是,这个假设不适用于我的情况。因此,我需要为满足谓词的列表定义一个自定义生成器。
如何定义一个从空列表开始并使用新的随机元素扩展它的自定义生成器,直到列表满足谓词?
我可能需要使用gen { }
生成器的计算表达式,但我不知道如何。
PS:我知道,与 的原始实现不同wellFormedList
,这种自定义生成器的分布在满足谓词的所有列表中并不统一。
解决方案
好吧,如果我理解正确,我认为应该这样做:
let wellFormedList (predicate:'a list -> bool) (myGen:Gen<'a>) =
gen {
let! initialList = Gen.listOf myGen
let mutable myList = initialList
while not <| predicate myList do
let! newVal = myGen
myList <- (newVal :: myList)
return myList
}
或者如果你想要一个递归函数:
let wellFormedList (predicate:'a list -> bool) (myGen:Gen<'a>) =
gen {
let rec addIfNecessary listSoFar =
if predicate listSoFar
then gen { return listSoFar }
else gen {
let! newVal = myGen
return! addIfNecessary (newVal :: listSoFar)
}
let! initialList = Gen.listOf myGen
return! addIfNecessary initialList
}
我还没有检查给你什么样的分布。当然,如果列表永远不会收敛于通过谓词的形式,那么您将面临无限循环(或堆栈溢出)的风险。
推荐阅读
- entity-framework - 在 .Net Core Web Api 的 POST 请求中省略 Id 属性
- ionic-framework - Ionic 社区版本是否支持实时更新又名“新版本可用”通知?
- javascript - RegEx 将字符组合成一个单词
- google-cloud-platform - ClassNotFoundException - 在构建图像并使用 BitBucket 管道中的 jib-maven-plugin 将其推送到 GCR 时
- javascript - 使用数组Javascript返回字符串
- javascript - Electron:Webview 网页通知点击事件
- jenkins - 如何从 Groovy 脚本中检索 Jenkins 环境?
- docker - 创建 Docker 映像时的问题
- vuejs2 - 尝试从 data 属性中获取更改数据并在 vuejs 中相应地更新计算属性
- kotlin - 为什么这个 Koltin 代码会抛出错误 Type mismatch: inferred type is {Comparable<*>? & java.io.Serializable?} 但任何预期