【问题标题】:Only generate positive integers with QuickCheck仅使用 QuickCheck 生成正整数
【发布时间】:2016-09-02 11:39:12
【问题描述】:

我们有两个函数比较两个不同的power 函数,如果它们返回相同的值(在相同的输入上),则返回 true。

然后我们有另外两个函数,它们针对两个列表测试这些函数,看看是否有任何不返回 true 的值。

但我们不想使用使用范围 [1..100] 的列表,而是使用 QuickCheck。

是否可以让 QuickCheck 只返回正整数?

代码:

comparePower1 :: Integer -> Integer -> Bool
comparePower1 n k = power n k == power1 n k

comparePower2 :: Integer -> Integer -> Bool
comparePower2 n k = power n k == power2 n k

testing1 = and [comparePower1 n k | n <- [0..100], k <- [0..100]]
testing2 = and [comparePower2 n k | n <- [0..100], k <- [0..100]]

【问题讨论】:

  • 也许stackoverflow.com/questions/12466580/… 会有所帮助?
  • @TomaszLewowski 不是。我不明白这种类型的类/定义(Integral a, Show a, Read a) =&gt; ...
  • 生成器使用suchThat修饰符怎么样?

标签: haskell testing quickcheck


【解决方案1】:

QuickCheck 支持Positive numbers,但为了本教程,我将向您展示如何创建自己的生成器。 QuickCheck 的主要功能之一是您可以设计自己的生成器来输出您需要的内容。比如

genPos :: Gen Int
genPos = abs `fmap` (arbitrary :: Gen Int) `suchThat` (> 0)

然后你可以创建自己的列表生成器

genListOfPos :: Gen [Int]
genListOfPos = listOf genPos

终于可以用forAll了,传递生成器和利润。

main :: IO ()
main = do
  quickCheck $ forAll genPos $ \x -> x > 0
  quickCheck $ forAll genListOfPos $ all (> 0)

【讨论】:

  • 谢谢,成功了!一个问题:为什么我不需要将新列表应用于测试功能,或者至少删除那里的现有列表([1..100])?或者我的问题应该是,该列表现在的功能到底是什么?
  • all (&gt; 0) 扩展为\xs -&gt; all (\x -&gt; x &gt; 0) xs,这意味着将\x -&gt; x &gt; 0 应用于xs 的每个元素,然后运行all 以检查是否所有元素都是True
  • 为了效率,最好生成一个Word,加1,强制转换为Int,取绝对值,然后折零。这可能更好的原因是我相信 QuickCheck 通常会尝试选择主要是“小”值,因此您可能会丢弃很多零。但是,在接受此建议之前,您必须检查一些细节——我可能是错的。
  • 如果这是真的,那就试试吧。另一种解决方案是在生成的数字上加 1(除非是 maxBound :: int),而不是过滤 &gt; 0
  • 那么你究竟是如何在 GHCi 上调用它的呢? quickCheck (forAll genListOfPos (all (> 0)) comparePower2?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多