Portability  Requires RankNTypes 

Stability  experimental 
Maintainer  Bas van Dijk <v.dijk.bas@gmail.com> 
This module defines the class MonadTransControl
of monad transformers
through which control operations can be lifted. Instances are
included for all the standard monad transformers from the
transformers
library except ContT
.
idLiftControl
and liftLiftControlBase
are provided to assist creation of
MonadControlIO
like classes (see Control.Monad.IO.Control) based on core
monads other than IO
.
 class MonadTrans t => MonadTransControl t where
 liftControl :: (Monad m, Monad n, Monad o) => (Run t n o > m a) > t m a
 type Run t n o = forall b. t n b > n (t o b)
 control :: (Monad n, Monad m, Monad o, Monad (t m), MonadTransControl t) => (Run t n o > m (t m a)) > t m a
 idLiftControl :: Monad m => ((forall b. m b > m (m b)) > m a) > m a
 type RunInBase m base = forall b. m b > base (m b)
 liftLiftControlBase :: (MonadTransControl t, Monad base, Monad m, Monad (t m)) => ((RunInBase m base > base a) > m a) > (RunInBase (t m) base > base a) > t m a
MonadTransControl
class MonadTrans t => MonadTransControl t whereSource
MonadTransControl
is the class of monad transformers supporting an
extra operation liftControl
, enabling control operations (functions that
use monadic actions as input instead of just output) to be lifted
through the transformer.
liftControl :: (Monad m, Monad n, Monad o) => (Run t n o > m a) > t m aSource
liftControl
is used to peel off the outer layer of a transformed
monadic action, allowing an transformed action t m a
to be
treated as a base action m b
.
More precisely, liftControl
captures the monadic state of t
at the
point where it is bound (in t n
), yielding a function of type
this function runs a transformed monadic action Run
t n o = t n a > n (t o a)t n a
in the base monad n
using the captured state, and leaves the
result t o a
in the monad n
after all side effects in n
have occurred.
This can be used to lift control operations with types such as
M a > M a
into the transformed monad t M
:
instance Monad M foo :: M a > M a foo' :: (MonadTransControl
t,Monad
(t M)) => t M a > t M a foo' a =control
$ run >  run :: t M a > M (t M a) foo $ run a  uses foo :: M (t M a) > M (t M a)
liftControl
is typically used with m == n == o
, but is required to
be polymorphic for greater type safety: for example, this type
ensures that the result of running the action in m
has no
remaining side effects in m
.
MonadTransControl MaybeT  
MonadTransControl ListT  
MonadTransControl IdentityT  
Monoid w => MonadTransControl (WriterT w)  
Monoid w => MonadTransControl (WriterT w)  
MonadTransControl (StateT s)  
MonadTransControl (StateT s)  
MonadTransControl (ReaderT r)  
Error e => MonadTransControl (ErrorT e)  
Monoid w => MonadTransControl (RWST r w s)  
Monoid w => MonadTransControl (RWST r w s) 
control :: (Monad n, Monad m, Monad o, Monad (t m), MonadTransControl t) => (Run t n o > m (t m a)) > t m aSource
An often used composition: control =
join
. liftControl
Lifting
idLiftControl :: Monad m => ((forall b. m b > m (m b)) > m a) > m aSource
idLiftControl
acts as the "identity" liftControl
operation from a monad
m
to itself.
idLiftControl f = f $ liftM return
It serves as the base case for a class like MonadControlIO
, which
allows control operations in some base monad (here IO
) to be
lifted through arbitrary stacks of zero or more monad transformers
in one call. For example, Control.Monad.IO.Control defines
class MonadIO m => MonadControlIO m where liftControlIO :: (RunInBase m IO > IO b) > m b
instance MonadControlIO IO where liftControlIO = idLiftControl
:: (MonadTransControl t, Monad base, Monad m, Monad (t m))  
=> ((RunInBase m base > base a) > m a) 

> (RunInBase (t m) base > base a) > t m a 
liftLiftControlBase
is used to compose two liftControl
operations:
the outer provided by a MonadTransControl
instance,
and the inner provided as the argument.
It satisfies
.
liftLiftControlBase
idLiftControl
== liftControl
It serves as the induction step of a MonadControlIO
like class. For
example, Control.Monad.IO.Control defines
instance MonadControlIO m => MonadControlIO (StateT s m) where liftControlIO = liftLiftControlBase liftControlIO
using the MonadTransControl
instance of
.
StateT
s