Haskell quickCheck property for half Evens

313 Views Asked by At

I have a program that takes a list and halves each even number in a list

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

and I want to write a quickCheck property for this functions which verifies if the initial and the compiled lists are equal if and only if there's no even number in that list

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

My problem is that this property failed after 3 tests. I have no idea what I'm doing wrong. Is the property I wrote wrong?

2

There are 2 best solutions below

0
On

the initial and the compiled lists are equal if and only if there's no even number in that list

Counterexample: [0] contains an even number and is unaffected by halfEvens.

You need to restrict that property to lists of nonzero elements. Exploit (==>) accordingly.

2
On

I want [...] a quickCheck property for this functions which verifies if the initial and the compiled lists are equal if and only if there's no even number in that list.

That's not what you're testing. You're testing that two properties hold:

A && B

However, you want either both of them (A && B), or none (not (A || B)):

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

Therefore, you would test something like

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

If you want to use a list of odd numbers for testing use forAll together with the right Gen:

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