满足谓词的 FsCheck 自定义列表生成器
FsCheck custom generator of lists satisfying a predicate
对于给定的谓词 pred : 'a list -> bool
和生成器 gen : Gen<'a>
,请考虑以下满足谓词的格式良好列表的生成器:
let wellFormedList pred gen =
Gen.ofList gen
|> Gen.filter pred
如 FsCheck manual 中所述,谓词对随机列表成立的可能性应该很高。
不幸的是,这个假设在我的案例中不成立。因此,我需要为满足谓词的列表定义自定义生成器。
我如何定义一个自定义生成器,它从空列表开始并用新的随机元素扩展它,直到列表满足谓词?
我可能需要为生成器使用计算表达式 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
}
不过我还没有检查给你什么样的发行版。当然,如果列表永远不会收敛到通过谓词的形式,你就有无限循环(或堆栈溢出)的风险。
对于给定的谓词 pred : 'a list -> bool
和生成器 gen : Gen<'a>
,请考虑以下满足谓词的格式良好列表的生成器:
let wellFormedList pred gen =
Gen.ofList gen
|> Gen.filter pred
如 FsCheck manual 中所述,谓词对随机列表成立的可能性应该很高。 不幸的是,这个假设在我的案例中不成立。因此,我需要为满足谓词的列表定义自定义生成器。
我如何定义一个自定义生成器,它从空列表开始并用新的随机元素扩展它,直到列表满足谓词?
我可能需要为生成器使用计算表达式 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
}
不过我还没有检查给你什么样的发行版。当然,如果列表永远不会收敛到通过谓词的形式,你就有无限循环(或堆栈溢出)的风险。