module Exercises where import Test.QuickCheck import Test.QuickCheck.Checkers --- 1 data Pair a = Pair a a deriving (Show, Eq) instance Functor Pair where fmap f (Pair x y) = Pair (f x) (f y) instance Applicative Pair where pure f = Pair f f (Pair f f') <*> (Pair x y) = Pair (f x) (f' y) instance Arbitrary a => Arbitrary (Pair a) where arbitrary = do x <- arbitrary y <- arbitrary return $ Pair x y instance Eq a => EqProp (Pair a) where (=-=) = eq --- 2 data Two a b = Two a b deriving (Show, Eq) instance Functor (Two a) where fmap f (Two x y) = Two x (f y) instance Monoid a => Applicative (Two a) where pure x = Two mempty $ x (Two f f') <*> (Two x y) = Two (mappend f x) (f' y) instance (Arbitrary a, Arbitrary b) => Arbitrary (Two a b) where arbitrary = do x <- arbitrary y <- arbitrary return $ Two x y instance (Eq a, Eq b) => EqProp (Two a b) where (=-=) = eq --- 3 data Three a b c = Three a b c deriving (Show, Eq) instance Functor (Three a b) where fmap f (Three x y z) = Three x y (f z) instance (Monoid a, Monoid b) => Applicative (Three a b) where pure x = Three mempty mempty x (Three f f' f'') <*> (Three x y z) = Three (mappend f x) (mappend f' y) (f'' z) instance (Arbitrary a, Arbitrary b, Arbitrary c) => Arbitrary (Three a b c) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary return $ Three x y z instance (Eq a, Eq b, Eq c) => EqProp (Three a b c) where (=-=) = eq --- 4 data Three' a b = Three' a b b deriving (Show, Eq) instance Functor (Three' a) where fmap f (Three' x y z) = Three' x (f y) (f z) instance (Monoid a) => Applicative (Three' a) where pure x = Three' mempty x x (Three' f f' f'') <*> (Three' x y z) = Three' (mappend f x) (f' y) (f'' z) instance (Arbitrary a, Arbitrary b) => Arbitrary (Three' a b) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary return $ Three' x y z instance (Eq a, Eq b) => EqProp (Three' a b) where (=-=) = eq --- 5 data Four a b c d = Four a b c d deriving (Show, Eq) instance Functor (Four a b c) where fmap f (Four x y z t) = Four x y z (f t) instance (Monoid a, Monoid b, Monoid c) => Applicative (Four a b c) where pure x = Four mempty mempty mempty x (Four f f' f'' f''') <*> (Four x y z t) = Four (mappend f x) (mappend f' y) (mappend f'' z) (f''' t) instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d) => Arbitrary (Four a b c d) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary t <- arbitrary return $ Four x y z t instance (Eq a, Eq b, Eq c, Eq d) => EqProp (Four a b c d) where (=-=) = eq --- 5 data Four' a b = Four' a a a b deriving (Show, Eq) instance Functor (Four' a) where fmap f (Four' x y z t) = Four' x y z (f t) instance (Monoid a) => Applicative (Four' a) where pure x = Four' mempty mempty mempty x (Four' f f' f'' f''') <*> (Four' x y z t) = Four' (mappend f x) (mappend f' y) (mappend f'' z) (f''' t) instance (Arbitrary a, Arbitrary b) => Arbitrary (Four' a b) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary t <- arbitrary return $ Four' x y z t instance (Eq a, Eq b) => EqProp (Four' a b) where (=-=) = eq