{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Lib where
{-
This is a simple environment Monad transformer called simply E. It has no
use whatsoever except to show the basics of how to construct such a thing.
It turns out that it's easier in most cases to write a monad transformer
than it is to write a monad, because the "heavy lifting" can in most cases
be forwarded to the transformed monad. (At the cost of some efficiency,
though newtype helps a lot with this.)
Don't use this. Use ReaderT instead.
-}
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Reader.Class (MonadReader(..))
import Control.Monad.Trans (MonadTrans(..))
newtype E r m a = E { runE :: r -> m a }
instance Functor m => Functor (E r m) where
fmap f (E a) = E $ fmap f . a
instance Applicative m => Applicative (E r m) where
pure = E . const . pure
(E f) <*> (E a) = E $ \r -> f r <*> a r
instance Monad m => Monad (E r m) where
return = pure
(E a) >>= f = E $ \r -> a r >>= \b -> runE (f b) r
instance MonadTrans (E r) where
lift = E . const
instance MonadIO m => MonadIO (E r m) where
liftIO = lift . liftIO
instance Monad m => MonadReader r (E r m) where
ask = E return
local t (E a) = E $ a . t
Comments
0 B
|👍
/👎
0 B
|👍
/👎