2021-01-19 13:45:54 +03:00
|
|
|
module Control.Monad.Reader.Interface
|
2021-01-19 17:12:36 +03:00
|
|
|
|
|
|
|
import Control.Monad.Maybe
|
|
|
|
import Control.Monad.Error.Either
|
|
|
|
import Control.Monad.Reader.Reader
|
|
|
|
import Control.Monad.State.State
|
2021-01-20 07:45:32 +03:00
|
|
|
import Control.Monad.RWS.CPS
|
2021-01-19 17:12:36 +03:00
|
|
|
import Control.Monad.Trans
|
|
|
|
import Control.Monad.Writer.CPS
|
|
|
|
|
2021-06-09 17:13:54 +03:00
|
|
|
%default total
|
2021-06-09 01:05:10 +03:00
|
|
|
|
2021-01-19 17:12:36 +03:00
|
|
|
||| A computation which runs in a static context and produces an output
|
|
|
|
public export
|
|
|
|
interface Monad m => MonadReader stateType m | m where
|
|
|
|
||| Get the context
|
|
|
|
ask : m stateType
|
|
|
|
|
|
|
|
||| `local f c` runs the computation `c` in an environment modified by `f`.
|
2021-06-09 17:13:54 +03:00
|
|
|
local : (stateType -> stateType) -> m a -> m a
|
2021-01-19 17:12:36 +03:00
|
|
|
|
|
|
|
|
|
|
|
||| Evaluate a function in the context held by this computation
|
|
|
|
public export
|
|
|
|
asks : MonadReader stateType m => (stateType -> a) -> m a
|
2021-01-20 07:45:32 +03:00
|
|
|
asks f = map f ask
|
2021-01-19 17:12:36 +03:00
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
-- Implementations
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
public export %inline
|
|
|
|
Monad m => MonadReader stateType (ReaderT stateType m) where
|
|
|
|
ask = MkReaderT (\st => pure st)
|
|
|
|
|
|
|
|
local f (MkReaderT action) = MkReaderT (action . f)
|
|
|
|
|
|
|
|
public export %inline
|
|
|
|
Monad m => MonadReader r (RWST r w s m) where
|
2021-08-10 21:24:32 +03:00
|
|
|
ask = MkRWST $ \r,s,w => pure (r,s,w)
|
|
|
|
local f m = MkRWST $ \r,s,w => unRWST m (f r) s w
|
2021-01-19 17:12:36 +03:00
|
|
|
|
|
|
|
public export %inline
|
|
|
|
MonadReader r m => MonadReader r (EitherT e m) where
|
|
|
|
ask = lift ask
|
|
|
|
local = mapEitherT . local
|
|
|
|
|
|
|
|
public export %inline
|
|
|
|
MonadReader r m => MonadReader r (MaybeT m) where
|
|
|
|
ask = lift ask
|
|
|
|
local = mapMaybeT . local
|
|
|
|
|
|
|
|
public export %inline
|
|
|
|
MonadReader r m => MonadReader r (StateT s m) where
|
|
|
|
ask = lift ask
|
|
|
|
local = mapStateT . local
|
|
|
|
|
|
|
|
public export %inline
|
|
|
|
MonadReader r m => MonadReader r (WriterT w m) where
|
|
|
|
ask = lift ask
|
|
|
|
|
|
|
|
-- this differs from the implementation in the mtl package
|
|
|
|
-- which uses mapWriterT. However, it seems strange that
|
|
|
|
-- this should require a Monoid instance to further
|
|
|
|
-- accumulate values, while the implementation of
|
|
|
|
-- MonadReader for RWST does no such thing.
|
2021-08-10 21:24:32 +03:00
|
|
|
local f (MkWriterT m) = MkWriterT $ \w => local f (m w)
|