Checkers is a library for reusable QuickCheck properties, particularly for standard type classes
How do I write a checkers instance to test whether my applicative instance of Validation is valid?
import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
import Control.Applicative
import Data.Monoid
data Validation e a =
Error e
| Scss a
deriving (Eq, Show)
instance Functor (Validation e) where
fmap _ (Error e) = Error e
fmap f (Scss a) = Scss $ f a
instance Monoid e => Applicative (Validation e) where
pure = Scss
(<*>) (Scss f) (Scss a) = Scss $ f a
(<*>) (Error g) (Scss a) = Error g
(<*>) (Scss a) (Error g) = Error g
(<*>) (Error a) (Error g) = Error $ mappend a g
instance (Arbitrary a, Arbitrary b) => Arbitrary (Validation a b) where
arbitrary = do
a <- arbitrary
b <- arbitrary
elements [Scss a, Error b]
instance (Eq a, Eq b) => EqProp (Validation a b) where (=-=) = eq
main :: IO ()
main = quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
I think I am almost there, but I get an error like:
chap17/Validation_applicative.hs:36:21: No instance for (CoArbitrary (Validation e0 [Char])) …
arising from a use of ‘applicative’
In the second argument of ‘($)’, namely
‘applicative [(Scss "b", Scss "a", Scss "c")]’
In the expression:
quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
In an equation for ‘main’:
main = quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
Compilation failed.
I have tried adding a CoArbitrary instance for Validation like so:
instance CoArbitrary (Validation a b)
but this leads to this error message:
chap17/Validation_applicative.hs:35:10: No instance for (GHC.Generics.Generic (Validation a b)) …
arising from a use of ‘Test.QuickCheck.Arbitrary.$gdmcoarbitrary’
In the expression: Test.QuickCheck.Arbitrary.$gdmcoarbitrary
In an equation for ‘coarbitrary’:
coarbitrary = Test.QuickCheck.Arbitrary.$gdmcoarbitrary
In the instance declaration for ‘CoArbitrary (Validation a b)’
chap17/Validation_applicative.hs:38:21: No instance for (Eq e0) arising from a use of ‘applicative’ …
The type variable ‘e0’ is ambiguous
Note: there are several potential instances:
instance Eq a => Eq (Const a b) -- Defined in ‘Control.Applicative’
instance Eq a => Eq (ZipList a) -- Defined in ‘Control.Applicative’
instance Eq a => Eq (Data.Complex.Complex a)
-- Defined in ‘Data.Complex’
...plus 65 others
In the second argument of ‘($)’, namely
‘applicative [(Scss "b", Scss "a", Scss "c")]’
In the expression:
quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
In an equation for ‘main’:
main = quickBatch $ applicative [(Scss "b", Scss "a", Scss "c")]
Compilation failed.