module Control.Monad.Readers
( module Control.Monad.Reader
, MonadReaders(ask, local)
, asks
) where
import Control.Monad.Reader hiding (MonadReader(ask, local, reader), asks)
import qualified Control.Monad.Reader as MTL (ask, local)
import Control.Monad.State (StateT, get, evalStateT)
import Control.Monad.Writer (runWriterT, WriterT)
class Monad m => MonadReaders r m where
ask :: m r
ask = reader id
local :: (r -> r) -> m a -> m a
reader :: (r -> a) -> m a
reader f = do
r <- ask
return (f r)
instance Monad m => MonadReaders r (ReaderT r m) where
ask = MTL.ask
local = MTL.local
instance (Monad m, MonadReaders r m) => MonadReaders r (StateT s m) where
ask = lift ask
local f action = get >>= lift . local f . evalStateT action
instance (Monad m, Monoid w, MonadReaders r m) => MonadReaders r (WriterT w m) where
ask = lift ask
local f action = lift (local f (runWriterT action >>= return . fst))
asks :: MonadReaders r m
=> (r -> a)
-> m a
asks = reader