半个Evens的Haskell quickCheck属性

时间:2014-12-01 14:56:56

标签: haskell quickcheck

我有一个程序可以获取一个列表并将列表中的每个偶数减半

halfEvens :: [Int] -> [Int]
halfEvens xs = [if x `mod` 2 == 0 then x `div` 2 else x | x <- xs]

我想为这个函数编写一个quickCheck属性,用于验证初始列表和编译列表是否相等,当且仅当该列表中没有偶数时

prop_evens xs = ((halfEvens xs == xs) && (length (filter (even) xs) == 0))

我的问题是这个属性在3次测试后失败了。 我不知道我做错了什么。我写错了属性吗?

2 个答案:

答案 0 :(得分:2)

  

我想要这个函数的quickCheck属性,它验证初始列表和编译列表是否相等,当且仅当该列表中没有偶数时。

这不是你正在测试的。您正在测试两个属性是否成立:

A && B

但是,你想要他们两个(A && B)或没有(not (A || B)):

(A && B) || not (A || B) -- which is the same as A == B

因此,您可以测试类似

的内容
prop_evens xs = p1 == p2
  where p1 = halfEvens xs == xs
        p2 = length (filter (even) xs) == 0

如果您想使用奇数列表进行测试,请使用forAll和右Gen

property $ forAll (listOf $ arbitrary `suchThat` odd) $ prop_evens

答案 1 :(得分:1)

  

当且仅当没有时,初始列表和编译列表是相等的   该列表中的偶数

反例:[0]包含偶数,不受halfEvens的影响。

您需要将该属性限制为非零元素列表。 相应地利用(==>)