module Lib where import Data.Monoid import Data.Traversable import Test.QuickCheck import Test.QuickCheck.Checkers -- -- Identity -- newtype Identity a = Identity a deriving (Eq, Ord, Show) instance Functor Identity where fmap f (Identity x) = Identity $ f x instance Applicative Identity where pure = Identity (Identity f) <*> x = fmap f x instance Foldable Identity where foldr f acc (Identity x) = f x acc instance Arbitrary a => Arbitrary (Identity a) where arbitrary = fmap Identity $ arbitrary instance Eq a => EqProp (Identity a) where (=-=) = eq instance Traversable Identity where traverse f (Identity x) = Identity <$> f x -- -- Constant -- newtype Constant a b = Constant { getConstant :: a } deriving (Eq, Ord, Show) instance Functor (Constant a) where fmap _ (Constant x) = Constant x instance Monoid a => Applicative (Constant a) where pure _ = Constant mempty (Constant x) <*> (Constant y) = Constant $ mappend x y instance (Arbitrary a, Arbitrary b) => Arbitrary (Constant a b) where arbitrary = do x <- arbitrary return $ Constant x instance (Eq a, Eq b) => EqProp (Constant a b) where (=-=) = eq instance Foldable (Constant a) where foldMap _ (Constant _) = mempty instance Traversable (Constant a) where traverse f (Constant x) = pure $ Constant x -- -- Maybe -- data Optional a = Nada | Yep a deriving (Show, Eq, Ord) instance Monoid a => Monoid (Optional a) where mempty = Nada mappend Nada _ = Nada mappend _ Nada = Nada mappend (Yep x) (Yep y) = Yep $ mappend x y instance Applicative Optional where pure = Yep (Yep f) <*> (Yep x) = Yep $ f x Nada <*> (Yep x) = Nada _ <*> Nada = Nada instance Functor Optional where fmap _ Nada = Nada fmap f (Yep x) = Yep $ f x instance Foldable Optional where foldr f acc Nada = acc foldr f acc (Yep x) = f x acc instance Traversable Optional where traverse f Nada = pure Nada traverse f (Yep x) = Yep <$> f x instance (CoArbitrary a, Arbitrary a) => Arbitrary (Optional a) where arbitrary = do x <- arbitrary frequency [ (1, return Nada) , (2, return $ Yep x) ] instance (Eq a) => EqProp (Optional a) where (=-=) = eq -- -- List -- data List a = Nil | Cons a (List a) deriving (Eq, Show) instance Functor List where fmap _ Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap f xs) instance Foldable List where foldr _ acc Nil = acc foldr f acc (Cons x xs) = f x (foldr f acc xs) instance Traversable List where sequenceA Nil = pure Nil sequenceA (Cons x xs) = Cons <$> x <*> (sequenceA xs) instance Arbitrary a => Arbitrary (List a) where arbitrary = sized go where go 0 = pure Nil go n = do xs <- go (n - 1) x <- arbitrary return $ Cons x xs instance (Eq a) => EqProp (List a) where (=-=) = eq -- -- Three -- 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 Foldable (Three a b) where foldr f acc (Three x y z) = (f z acc) instance Traversable (Three a b) where traverse f (Three x y z) = fmap (Three x 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 -- -- Pair -- data Pair a b = Pair a b deriving (Eq, Show) instance Functor (Pair a) where fmap f (Pair x y) = Pair x (f y) instance Foldable (Pair a) where foldr f acc (Pair x y) = (f y acc) instance Traversable (Pair a) where traverse f (Pair x y) = fmap (Pair x) (f y) instance (Arbitrary a, Arbitrary b) => Arbitrary (Pair a b) where arbitrary = do x <- arbitrary y <- arbitrary return $ Pair x y instance (Eq a, Eq b) => EqProp (Pair a b) where (=-=) = eq -- -- Big -- data Big a b = Big a b b deriving (Eq, Show) instance Functor (Big a) where fmap f (Big x y z) = Big x (f y) (f z) instance Foldable (Big a) where foldr f acc (Big _ y z) = (f y (f z acc)) instance Traversable (Big a) where traverse f (Big x y z) = (Big x) <$> (f y) <*> (f z) instance (Arbitrary a, Arbitrary b) => Arbitrary (Big a b) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary return $ Big x y z instance (Eq a, Eq b) => EqProp (Big a b) where (=-=) = eq -- -- Bigger -- data Bigger a b = Bigger a b b b deriving (Eq, Show) instance Functor (Bigger a) where fmap f (Bigger x y z t) = Bigger x (f y) (f z) (f t) instance Foldable (Bigger a) where foldr f acc (Bigger _ y z t) = f y $ f z $ f t acc instance Traversable (Bigger a) where traverse f (Bigger x y z t) = (Bigger x) <$> (f y) <*> (f z) <*> (f t) instance (Arbitrary a, Arbitrary b) => Arbitrary (Bigger a b) where arbitrary = do x <- arbitrary y <- arbitrary z <- arbitrary t <- arbitrary return $ Bigger x y z t instance (Eq a, Eq b) => EqProp (Bigger a b) where (=-=) = eq