{-# LANGUAGE InstanceSigs #-} class Monoid' a where mempty' :: a mappend' :: a -> a -> a class MyFunctor f where my_fmap :: (a -> b) -> f a -> f b instance MyFunctor Maybe where my_fmap :: (a -> b) -> Maybe a -> Maybe b my_fmap f Nothing = Nothing my_fmap f (Just x) = Just (f x) instance MyFunctor [] where my_fmap :: (a -> b) -> [a] -> [b] my_fmap f [] = [] my_fmap f (x:xs) = f x : my_fmap f xs class (MyFunctor m) => MyMonad m where my_return :: a -> m a my_join :: m (m a) -> m a instance MyMonad [] where my_return :: a -> [a] my_return x = [x] my_join :: [[a]] -> [a] my_join = concat my_bind :: (MyMonad m) => m a -> (a -> m b) -> m b my_bind x f = my_join (my_fmap f x) join' :: (Monad' m) => m (m a) -> m a join' c = bind' c (\ x -> x) class (MyFunctor m) => Monad' m where return' :: a -> m a bind' :: m a -> (a -> m b) -> m b instance Monad' Maybe where return' :: a -> Maybe a return' x = Just x bind' :: Maybe a -> (a -> Maybe b) -> Maybe b bind' Nothing f = Nothing bind' (Just x) f = f x instance Monad' [] where return' :: a -> [a] return' x = [x] bind' :: [a] -> (a -> [b]) -> [b] bind' [] f = [] bind' (x:xs) f = f x ++ bind' xs f