#if MTL
#endif
module Control.Effect.Reader (
EffectReader, Reader, runReader,
ask, asks, local
) where
import Control.Monad.Effect
#ifdef MTL
import qualified Control.Monad.Reader.Class as R
instance EffectReader r es => R.MonadReader r (Effect es) where
ask = ask
local = local
reader = asks
#endif
newtype Reader r a = Reader (r -> a)
deriving Functor
type EffectReader r es = (Member (Reader r) es, r ~ ReaderType es)
type family ReaderType es where
ReaderType (Reader r ': es) = r
ReaderType (e ': es) = ReaderType es
ask :: EffectReader r es => Effect es r
ask = asks id
asks :: EffectReader r es => (r -> a) -> Effect es a
asks = send . Reader
local :: EffectReader r es => (r -> r) -> Effect es a -> Effect es a
local f effect = do
env <- asks f
run env effect
where
run env =
handle return
$ intercept (bind env)
$ defaultRelay
runReader :: r -> Effect (Reader r ': es) a -> Effect es a
runReader env =
handle return
$ eliminate (bind env)
$ defaultRelay
bind :: r -> Reader r (Effect es b) -> Effect es b
bind env (Reader k) = k env