有谁知道如何使用 QuickCheck 在 Haskell 中定义生成器,以便只选择一次选择的元素?
我已经意识到我可能需要一个“Gen(Maybe Positive)”生成器,但当然这会产生重复的数字。我想要它,以便选择不重复的数字。在返回数字的情况下,我想要 Just return,而在随机数全部用尽的情况下,我希望 Gen Nothing 返回。
谢谢,
标记
有谁知道如何使用 QuickCheck 在 Haskell 中定义生成器,以便只选择一次选择的元素?
我已经意识到我可能需要一个“Gen(Maybe Positive)”生成器,但当然这会产生重复的数字。我想要它,以便选择不重复的数字。在返回数字的情况下,我想要 Just return,而在随机数全部用尽的情况下,我希望 Gen Nothing 返回。
谢谢,
标记
你不能。看看 的定义Gen
。到目前为止,它无法携带任何关于已选择内容的状态。给定相同的随机生成器和大小限制,它必须始终生成相同的结果。但是,您可以编写一个Eq a => Gen [a]
生成不重复值的列表。一个简单的(但有些天真)就是这样的。
uniques :: Eq a => Gen a -> Gen [a]
uniques gen = fmap nub $ listOf gen
QuickCheck 通常用于随机测试,而不是详尽的测试。有一些很棒的库可以处理详尽的测试——看看smallcheck和lazysmallcheck。
您可以为此使用permutations
(在模块中Data.List
)。
这是 的函数签名permutations
:
permutations :: [a] -> [[a]]
如您所见,它返回一个列表列表。这是一个小例子(使用 GHCi 7.0.4):
> permutations [1..3]
[[1,2,3],[2,1,3],[3,2,1],[2,3,1],[3,1,2],[1,3,2]]
因此,您可以执行以下操作:
prop_unique_elements = forAll (elements (permutations [1..3])) $ \x -> foo == bar
我还没有测试过,所以它需要一些按摩,但我希望它能清楚地传达这一点。祝你好运。