module Control.Effect.Environment
(EffEnvironment, runInEnvironment, ask, asks, mapEnvironment, liftReader,
effToReaderT, readerTToEff)
where
import Control.Effect
import Control.Monad.Morph (lift, hoist, generalize)
import Control.Monad.Trans.Reader (Reader, ReaderT(..))
import qualified Control.Monad.Trans.Reader as Reader
class (Monad m) => EffEnvironment env m | m -> env where
liftReader :: Reader env a -> m a
instance Monad m => EffEnvironment env (Eff (Reader env) m) where
liftReader = interpret
instance (EffEnvironment env m) => EffEnvironment env (Eff effects m) where
liftReader = lift . liftReader
ask :: (EffEnvironment env m) => m env
ask = liftReader Reader.ask
asks :: (EffEnvironment a m) => (a -> b) -> m b
asks f = fmap f ask
runInEnvironment
:: Monad m
=> Eff (Reader env) m a -> env -> m a
runInEnvironment = runReaderT . effToReaderT
mapEnvironment
:: (EffEnvironment env m)
=> (env -> env') -> Eff (Reader env') m a -> m a
mapEnvironment f m = ask >>= runInEnvironment m . f
effToReaderT :: Monad m => Eff (Reader e) m a -> ReaderT e m a
effToReaderT = translate (lift . hoist generalize)
readerTToEff :: (Monad m, EffEnvironment e m) => ReaderT e m a -> m a
readerTToEff m = ask >>= runReaderT m