-- Monad Transformer Summary (Lecture 5, AFP 2014) -- Patrik Jansson, Chalmers and U. of Gothenburg -- (This is not a complete Haskell file) ---------------------------------------------------------------- -- Functors and Monads (repetition) class Functor f where fmap :: (a -> b) -> (f a -> f b) -- Law.Id: fmap id == id -- Law.Cmp: fmap (f . g) == fmap f . fmap g class {- Functor m => -} Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a -- Law 1. return x >>= f == f x -- Law 2. m >>= return == m -- Law 3. (m >>= f) >>= g == m >>= (\x -> f x >>= g) -- Law 3'. (f >=> g) >=> h == f >=> (g >=> h) liftM :: (Monad m) => (a -> b) -> (m a -> m b) liftM2 :: (Monad m) => (a -> b -> c) -> (m a -> m b -> m c) ---------------------------------------------------------------- -- Control.Monad.Reader newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a } -- newtype Reader r a = Reader { runReader :: r -> a } type Reader r = ReaderT r Identity class (Monad m) => MonadReader r m | m -> r where ask :: m r local :: (r -> r) -> m a -> m a ---------------------------------------------------------------- -- Control.Monad.State newtype StateT s m a = StateT { runStateT :: s -> m (a, s) } -- newtype State s a = State { runState :: s -> (a, s) } type State s = StateT s Identity class (Monad m) => MonadState s m | m -> s where get :: m s put :: s -> m () gets :: (MonadState s m) => (s -> a) -> m a modify :: (MonadState s m) => (s -> s) -> m () ---------------------------------------------------------------- -- Control.Monad.Error data Either e a = Left e | Right a -- Haskell Prelude -- Either e is already MonadError newtype ErrorT e m a = ErrorT { runErrorT :: m (Either e a) } class (Monad m) => MonadError e m | m -> e where throwError :: e -> m a catchError :: m a -> (e -> m a) -> m a -- CMW is not used in the Lect. 5 application, but often useful ---------------------------------------------------------------- -- Control.Monad.Writer newtype WriterT w m a = WriterT { runWriterT :: m (a, w) } -- newtype Writer w a = Writer { runWriter :: (a, w) } type Writer w = WriterT w Identity instance (Monoid w, Monad m) => Monad (WriterT w m) class (Monoid w, Monad m) => MonadWriter w m | m -> w where tell :: w -> m () listen :: m a -> m (a, w) pass :: m (a, w -> w) -> m a