#if MTL
#endif
module Control.Effect.Reader (
EffectReader, Reader, runReader,
ask, asks, local,
stateReader
) where
import Control.Effect.State
import Control.Monad.Effect
#ifdef MTL
import Data.Type.Row
import qualified Control.Monad.Reader.Class as R
instance (Member (Reader r) l, Reader r ~ InstanceOf Reader l) => R.MonadReader r (Effect l) where
ask = ask
local = local
reader = asks
#endif
data Reader r a where
Ask :: Reader r r
type instance Is Reader f = IsReader f
type family IsReader f where
IsReader (Reader r) = 'True
IsReader f = 'False
class MemberEffect Reader (Reader r) l => EffectReader r l
instance MemberEffect Reader (Reader r) l => EffectReader r l
ask :: EffectReader r l => Effect l r
ask = send Ask
asks :: EffectReader r l => (r -> a) -> Effect l a
asks f = fmap f ask
local :: EffectReader r l => (r -> r) -> Effect l a -> Effect l a
local f effect = do
env <- asks f
intercept return (bind env) effect
stateReader :: EffectState s l => Effect (Reader s ':+ l) a -> Effect l a
stateReader = eliminate return (\Ask k -> get >>= k)
runReader :: r -> Effect (Reader r ':+ l) a -> Effect l a
runReader env = eliminate return (bind env)
bind :: r -> Reader r a -> (a -> s) -> s
bind env Ask k = k env