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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With