The MonadTransControl type class is a stronger version of MonadTrans:
Instances of MonadTrans know how to actions in the base monad to
the transformed monad. These lifted actions, however, are completely unaware
of the monadic state added by the transformer.lift
MonadTransControl instances are aware of the monadic state of the
transformer and allow to save and restore this state.
This allows to lift functions that have a monad transformer in both positive and negative position. Take, for example, the function
withFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
MonadTrans instances can only lift the return type of the withFile
function:
withFileLifted :: MonadTrans t => FilePath -> IOMode -> (Handle -> IO r) -> t IO r
withFileLifted file mode action = lift (withFile file mode action)
However, MonadTrans is not powerful enough to make withFileLifted
accept a function that returns t IO. The reason is that we need to take
away the transformer layer in order to pass the function to .
withFileMonadTransControl allows us to do this:
withFileLifted' :: (Monad (t IO), MonadTransControl t) => FilePath -> IOMode -> (Handle -> t IO r) -> t IO r
withFileLifted' file mode action = liftWith (\run -> withFile file mode (run . action)) >>= restoreT . return
Associated types
type family StT (t :: (Type -> Type) -> Type -> Type) aMonadic state of
t.The monadic state of a monad transformer is the result type of its
runfunction, e.g.:runReaderT :: ReaderT r m a -> r -> m a StT (ReaderT r) a ~ a runStateT :: StateT s m a -> s -> m (a, s) StT (StateT s) a ~ (a, s) runMaybeT :: MaybeT m a -> m (Maybe a) StT MaybeT a ~ Maybe aProvided type instances:
StT IdentityT a ~ a StT MaybeT a ~ Maybe a StT (ErrorTe) a ~Errore => Either e a StT (ExceptT e) a ~ Either e a StTListTa ~ [a] StT (ReaderT r) a ~ a StT (StateT s) a ~ (a, s) StT (WriterT w) a ~ Monoid w => (a, w) StT (RWST r w s) a ~ Monoid w => (a, s, w)
Methods
liftWith :: Monad m => (Run t -> m a) -> t m aliftWithis similar toliftin that it lifts a computation from the argument monad to the constructed monad.Instances should satisfy similar laws as the MonadTrans laws:
liftWith (\_ -> return a) = return aliftWith (\_ -> m >>= f) = liftWith (\_ -> m) >>= (\a -> liftWith (\_ -> f a))The difference with
liftis that before lifting themcomputationliftWithcaptures the state oft. It then provides themcomputation with a Run function that allows runningt ncomputations inn(for alln) on the captured state, e.g.withFileLifted :: (Monad (t IO), MonadTransControl t) => FilePath -> IOMode -> (Handle -> t IO r) -> t IO r withFileLifted file mode action = liftWith (\run -> withFile file mode (run . action)) >>= restoreT . returnIf the
Runfunction is ignored,liftWithcoincides withlift:lift f = liftWith (\_ -> f)Implementations use the
Runfunction associated with a transformer:liftWith :: Monad m => ((Monad n => ReaderT r n b -> n b) -> m a) -> ReaderT r m a liftWith f = ReaderT (\r -> f (\action -> runReaderT action r)) liftWith :: Monad m => ((Monad n => StateT s n b -> n (b, s)) -> m a) -> StateT s m a liftWith f = StateT (\s -> liftM (\x -> (x, s)) (f (\action -> runStateT action s))) liftWith :: Monad m => ((Monad n => MaybeT n b -> n (Maybe b)) -> m a) -> MaybeT m a liftWith f = MaybeT (liftMJust(f runMaybeT))restoreT :: Monad m => m (StT t a) -> t m aConstruct a
tcomputation from the monadic state oftthat is returned from a Run function.Instances should satisfy:
liftWith (\run -> run t) >>= restoreT . return = trestoreTis usually implemented through the constructor of the monad transformer:ReaderT :: (r -> m a) -> ReaderT r m a restoreT :: m a -> ReaderT r m a restoreT action = ReaderT { runReaderT = const action } StateT :: (s -> m (a, s)) -> StateT s m a restoreT :: m (a, s) -> StateT s m a restoreT action = StateT { runStateT = const action } MaybeT :: m (Maybe a) -> MaybeT m a restoreT :: m (Maybe a) -> MaybeT m a restoreT action = MaybeT actionExample type signatures:
restoreT :: Monad m => m a -> IdentityT m a restoreT :: Monad m => m (Maybe a) -> MaybeT m a restoreT :: (Monad m,Errore) => m (Either e a) ->ErrorTe m a restoreT :: Monad m => m (Either e a) -> ExceptT e m a restoreT :: Monad m => m [a] ->ListTm a restoreT :: Monad m => m a -> ReaderT r m a restoreT :: Monad m => m (a, s) -> StateT s m a restoreT :: (Monad m, Monoid w) => m (a, w) -> WriterT w m a restoreT :: (Monad m, Monoid w) => m (a, s, w) -> RWST r w s m a
Instances10MonadTransControl, …
MonadTransControl MaybeTDefined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonoid w => MonadTransControl (WriterT w)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonoid w => MonadTransControl (WriterT w)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonadTransControl IdentityTDefined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonadTransControl (ExceptT e)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonadTransControl (ReaderT r)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonadTransControl (StateT s)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonadTransControl (StateT s)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonoid w => MonadTransControl (RWST r w s)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.ControlMonoid w => MonadTransControl (RWST r w s)Defined in monad-control-1.0.3.1 · Control.Monad.Trans.Control