Tangential to the discussion, there is a nice idiom for using an alternative
typeclass that works well in the Quickcheck case: newtypes.
For example, if I have a test function:
testString :: String -> Bool
testString s = f1 s == f2 s
and the default instance of String isn't doing what I want, I could
define a custom arbitrary method:
testString = do
s <- myArbitraryStr
return (f1 s == f2 s)
But I could also newtype String, define an instance for that newtype,
and use either of these (in my opinion) nice alternative spellings:
testString (MyString s) = ...
testString = do
MyString s <- arbitrary
I especially like the first form.
Cheers,
Edward