Question

I've a function, rev, that returns some value for a type that is in three typeclasses:

rev :: (Integral a, Show a, Read a) => a -> a
rev = read . reverse . show

I'd like to test some property about it with quickcheck. Though, I'm not interested in testing negative values of Integral types because I'm using Integer by lack of a Natural type in the base library. So I thought, let's take the opposite of the value generated when the value generated is negative and I'll be fine:

prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool
prop_id n | n >= 0    = (rev.rev) n == n
          | otherwise = let n' = -n in (rev.rev) n' == n'

(the property tested isn't important here - in particular it doesn't hold for very basic values and I'm aware of that, it's not the subject of this question)

Then I ran into the Positive modifier and thought that although my test was now functionning, it'd be nice to implement it in a nicer way. So I tried:

prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool
prop_id n = (rev.rev) n == n

I must admit I was surprised when it compiled. But then an error popped when running the test:

*** Failed! Exception: 'Prelude.read: no parse' (after 1 test): 
Positive {getPositive = 1}

So I thought, "mmk, must declare this Positive thing an instance of Read". So I did just that, but the instance is already declared in the quickCheck library it seems because ghci screamed at me.

And at this point I'm lost, for I do not find good documentation (if any).

Any pointer helping me to understand modifiers and other nice things in the quickcheck library will be appreciated.

Was it helpful?

Solution

The common way of using these modifiers is to pattern match on them, e.g.

prop_id :: (Integral a, Show a, Read a) => Positive a -> Bool
prop_id (Positive n) = (rev.rev) n == n

This way, n will have the underlying type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top