How can I constraint QuickCheck parameters, e.g. only use non-negative ints?

haskell, quickcheck

Solution

Constraining wrappers (from `Test.QuickCheck.Modifiers`, if they aren't reexported implicitly) can be used in this way:

prop_Myfunc :: [Int] -> (NonNegative Int, NonNegative Int) -> Bool
prop_Myfunc ints (NonNegative i, NonNegative j) = ints !! i == ints !! j

You can treat `SomeWrapper a` as `a` with modified distribution. For example, `NonNegative a` ensures that `a >= 0`. After the wrapper was generated, the value can be get with pattern-matching or explicit accessor (`getNonNegative` in this case).

As for constraining the top margin of your indices, I think it's not possible with wrappers (it's impossible in the Haskkell type system to parameterise a type with the value, the list length in this case). However, with the `==>` operator you can add an arbitrary boolean constraint for your test:

prop_Myfunc ints (NonNegative i, NonNegative j) = i < l && j < l ==> ints !! i == ints !! j where
    l = length ints

It works in other way: when the condition isn't true, it simply discards the current test case. But be careful: if there are too many thrown cases (the condition is too restrictive), the test becomes much less useful. A „lossless“ behaviour can be often achieved with `shrink`ing test data, but it's a whole other topic.

Problem

I'm new to Haskell. It's very nice so far, but I'm running into copy-pasting for my QuickCheck properties, and I'd like to fix that. Here's a made-up example: ``` prop_Myfunc :: [Int] -> (Int,Int) -> Bool prop_Myfunc ints (i,j) = ints !! i == ints !! j ``` This won't work because QuickCheck generates negative numbers, so I get ``` *** Failed! (after 2 tests and 2 shrinks): Exception: Prelude.(!!): negative index ``` I've tried to google for solutions to this, and I've found e.g. NonNegative and ==>, but I don't understand how they work. How can I restrict the above example so that i and j are never negative? And also, so that neither is too high? That is: `0 <= i,j < length ints`

Original source