{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
module Control.Monad.Factory.Class(
MonadFactory(..)
, defer
, asksEnv
, withEnv
, modifyEnv
, runEnv
) where
class (Monad m, Monad n) => MonadFactory env n m | m -> env n where
getEnv :: m env
putEnv :: env -> m ()
produce
:: n component
-> (component -> n ())
-> m component
asksEnv :: MonadFactory env n m => (env -> a) -> m a
asksEnv f = f <$> getEnv
defer :: MonadFactory env n m => n () -> m ()
defer = produce (return ()) . const
withEnv :: MonadFactory env n m => (env -> m env) -> m ()
withEnv f = getEnv >>= f >>= putEnv
modifyEnv :: MonadFactory env n m => (env -> env) -> m ()
modifyEnv f = getEnv >>= putEnv . f
runEnv :: MonadFactory env n m => m c -> m (env, c)
runEnv ma = do
a <- ma
e <- getEnv
return (e, a)