This library provide set of generic properties for laws of standard type classes and limited way to compose them. Here are some examples:
Testing monoid laws
quickCheck $ eq $ prop_Monoid (T :: T [Int])+++ OK, passed 100 tests.
quickCheck $ eq $ prop_Monoid (T :: T (Maybe [Int]))+++ OK, passed 100 tests.
Testing functor laws
quickCheck $ eq $ prop_FunctorCompose (+2) (+199) (T :: T [Int])+++ OK, passed 100 tests.
All properties in this library are polymorphic. For example
property for checking associativity of
mappend could have
prop_mappend :: (Eq a, Monoid a) => a -> a -> a -> Bool
But if one tries to pass this expression to
quickCheck GHC will
rightfully complain that type is too generic. Indeed there is no
way to figure out what is type of a. Obvious way to fix type of
is to add type signature. However it's too cumbersome to write
signature for 3 parameter function.
Another approach was taken instead. All properties take dummy parameter which fix type:
prop_Mappend :: (Eq a, Monoid a) => T a -> a -> a -> a -> Bool
T is phanom typed unit. It ensures that only type information
could be passed to function. For example test invokation could look
quickCheck $ prop_Mappend (T :: T [Int])
By convention all user supplied parameters are placed before T and all quickcheck supplied parameters are after T.
Comparing for equality
A lot of QuickCheck properties have form
expression = another
expression. It's natural to compare them for equality however not
all types have
Eq instance. Functions are most prominent example.
There are three generic ways to compare values for equality.
- Convert value to some type with Eq instance and compare them. Caller must ensure that such conversion make sence
- Most generic: use custom comparison function.
This approach naturally generelizes to arbitrary boolean expressions of properties with this form.
- eq :: (Equalable a, Eq (Result a)) => a -> Compared a
- eqOn :: (Equalable a, Eq b) => (Result a -> b) -> a -> Compared a
- eqWith :: Equalable a => (Result a -> Result a -> Bool) -> a -> Compared a
- (.==.) :: a -> a -> Equal a
- (.&&.) :: Equalable a => a -> a -> a
- (.||.) :: Equalable a => a -> a -> a
- notE :: Equalable a => a -> a
- data T a = T
Convert to QuickCheck properies
Convert values to types which could be compare
Compare with custom function. Just a shorter sinonym for equalWith