Search code examples
haskellquickcheck

How do I write a QuickCheck property which expects a non-empty list of non-zero numbers?


This is a hack (cogsRpm is a user supplied function which is supposed to match the output of go):

propCheck ns = cogsRpm (ns ++ [42])  == go (ns ++ [42])

I added the 42 to stop quickcheck from generating zero length lists. It also could fail still though because it isn't supposed to have zeroes in there either.

I read the docs, but there are not enough examples for me to parse out how to actually use them. I did manage to get this on another case:

prop_check (Positive x) (Positive y)  = updateHealth x y == if y > x then 0 else x-y

Which forces positives, and I tried combining a bunch of things to get listOf1 and NonZero, but I could not figure out the syntax, hence the hack to add an element to the list. How can I avoid this hack?


Solution

  • QuickCheck comes bundled with a NonEmptyList newtype, whose Arbitrary instance only generates non-empty lists. You can combine this with NonZero to get a non-empty list of non-zero integers:

    propCheck :: NonEmptyList (NonZero Int) -> Bool
    propCheck (coerce -> ns) = cogsRpm ns == go ns
    

    I'm using coerce in a view pattern to tersely and efficiently turn the NonEmptyList (NonZero Int) back into a regular list of Ints.