| Stability | experimental |
|---|---|
| Maintainer | Bas van Dijk <v.dijk.bas@gmail.com> |
| Safe Haskell | Safe-Infered |
Control.Monad.Trans.Control
Description
(TODO: It would be nicer if the associated data types StT and StM were
associated type synonyms instead. This would simplify a lot of code and could
make some definitions more efficient because there'll be no need to wrap the
monadic state in a data type. Unfortunately GHC has a bug which prevents this:
http://hackage.haskell.org/trac/ghc/ticket/5595. I will switch to associated
type synonyms when that bug is fixed.)
- class MonadTrans t => MonadTransControl t where
- type Run t = forall n β. Monad n => t n β -> n (StT t β)
- class MonadBase b m => MonadBaseControl b m | m -> b where
- data StM m :: * -> *
- liftBaseWith :: (RunInBase m b -> b α) -> m α
- restoreM :: StM m α -> m α
- type RunInBase m b = forall α. m α -> b (StM m α)
- type ComposeSt t m α = StM m (StT t α)
- defaultLiftBaseWith :: (MonadTransControl t, MonadBaseControl b m) => (forall β. ComposeSt t m β -> StM (t m) β) -> (RunInBase (t m) b -> b α) -> t m α
- defaultRestoreM :: (MonadTransControl t, MonadBaseControl b m) => (StM (t m) α -> ComposeSt t m α) -> StM (t m) α -> t m α
- control :: MonadBaseControl b m => (RunInBase m b -> b (StM m α)) -> m α
- liftBaseOp :: MonadBaseControl b m => ((α -> b (StM m β)) -> b (StM m γ)) -> (α -> m β) -> m γ
- liftBaseOp_ :: MonadBaseControl b m => (b (StM m α) -> b (StM m β)) -> m α -> m β
- liftBaseDiscard :: MonadBaseControl b m => (b () -> b α) -> m () -> m α
Documentation
class MonadTrans t => MonadTransControl t whereSource
Methods
liftWith :: Monad m => (Run t -> m α) -> t m αSource
liftWith is similar to lift in that it lifts a computation from
the argument monad to the constructed monad.
Instances should satisfy similar laws as the MonadTrans laws:
liftWith . const . return = return
liftWith (const (m >>= f)) = liftWith (const m) >>= liftWith . const . f
The difference with lift is that before lifting the m computation
liftWith captures the state of t. It then provides the m
computation with a Run function that allows running t n computations in
n (for all n) on the captured state.
restoreT :: Monad m => m (StT t α) -> t m αSource
Construct a t computation from the monadic state of t that is
returned from a Run function.
Instances should satisfy:
liftWith (\run -> run t) >>= restoreT . return = t
Instances
| 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) |
class MonadBase b m => MonadBaseControl b m | m -> b whereSource
Methods
liftBaseWith :: (RunInBase m b -> b α) -> m αSource
liftBaseWith is similar to liftIO and liftBase in that it
lifts a base computation to the constructed monad.
Instances should satisfy similar laws as the MonadIO and MonadBase laws:
liftBaseWith . const . return = return
liftBaseWith (const (m >>= f)) = liftBaseWith (const m) >>= liftBaseWith . const . f
The difference with liftBase is that before lifting the base computation
liftBaseWith captures the state of m. It then provides the base
computation with a RunInBase function that allows running m
computations in the base monad on the captured state.
restoreM :: StM m α -> m αSource
Construct a m computation from the monadic state of m that is
returned from a RunInBase function.
Instances should satisfy:
liftBaseWith (\runInBase -> runInBase m) >>= restoreM = m
Instances
| MonadBaseControl [] [] | |
| MonadBaseControl IO IO | |
| MonadBaseControl STM STM | |
| MonadBaseControl Maybe Maybe | |
| MonadBaseControl Identity Identity | |
| MonadBaseControl b m => MonadBaseControl b (ListT m) | |
| MonadBaseControl b m => MonadBaseControl b (MaybeT m) | |
| MonadBaseControl b m => MonadBaseControl b (IdentityT m) | |
| (Monoid w, MonadBaseControl b m) => MonadBaseControl b (WriterT w m) | |
| (Monoid w, MonadBaseControl b m) => MonadBaseControl b (WriterT w m) | |
| (Error e, MonadBaseControl b m) => MonadBaseControl b (ErrorT e m) | |
| MonadBaseControl b m => MonadBaseControl b (StateT s m) | |
| MonadBaseControl b m => MonadBaseControl b (StateT s m) | |
| MonadBaseControl b m => MonadBaseControl b (ReaderT r m) | |
| (Monoid w, MonadBaseControl b m) => MonadBaseControl b (RWST r w s m) | |
| (Monoid w, MonadBaseControl b m) => MonadBaseControl b (RWST r w s m) | |
| MonadBaseControl ((->) r) ((->) r) | |
| MonadBaseControl (Either e) (Either e) | |
| MonadBaseControl (ST s) (ST s) | |
| MonadBaseControl (ST s) (ST s) |
type RunInBase m b = forall α. m α -> b (StM m α)Source
A function that runs a m computation on the monadic state that was
captured by liftBaseWith
A RunInBase m function yields a computation in the base monad of m that
returns the monadic state of m. This state can later be used to restore the
m computation using restoreM.
Defaults for MonadBaseControl
Note that by using the following default definitions it's easy to make a
monad transformer T an instance of MonadBaseControl:
instance MonadBaseControl b m => MonadBaseControl b (T m) where
newtype StM (T m) a = StMT {unStMT :: ComposeSt T m a}
liftBaseWith = defaultLiftBaseWith StMT
restoreM = defaultRestoreM unStMT
Defining an instance for a base monad B is equally straightforward:
instance MonadBaseControl B B where
newtype StM B a = StMB {unStMB :: a}
liftBaseWith f = f $ liftM StMB
restoreM = return . unStMB
type ComposeSt t m α = StM m (StT t α)Source
Handy type synonym that composes the monadic states of t and m.
It can be used to define the StM for new MonadBaseControl instances.
Arguments
| :: (MonadTransControl t, MonadBaseControl b m) | |
| => (forall β. ComposeSt t m β -> StM (t m) β) |
|
| -> (RunInBase (t m) b -> b α) -> t m α |
Default defintion for the liftBaseWith method.
Note that it composes a liftWith of t with a liftBaseWith of m to
give a liftBaseWith of t m:
defaultLiftBaseWith stM = \f ->liftWith$ \run ->liftBaseWith$ \runInBase -> f $ liftM stM . runInBase . run
Arguments
| :: (MonadTransControl t, MonadBaseControl b m) | |
| => (StM (t m) α -> ComposeSt t m α) |
|
| -> StM (t m) α -> t m α |
Utility functions
control :: MonadBaseControl b m => (RunInBase m b -> b (StM m α)) -> m αSource
An often used composition: control f =
liftBaseWith f >>= restoreM
liftBaseOp :: MonadBaseControl b m => ((α -> b (StM m β)) -> b (StM m γ)) -> (α -> m β) -> m γSource
liftBaseOp is a particular application of liftBaseWith that allows
lifting control operations of type:
((a -> b c) -> b c) to: (.
MonadBaseControl b m => (a -> m c) -> m c)
For example:
liftBaseOp alloca ::MonadBaseControlIOm => (Ptr a -> m c) -> m c
liftBaseOp_ :: MonadBaseControl b m => (b (StM m α) -> b (StM m β)) -> m α -> m βSource
liftBaseOp_ is a particular application of liftBaseWith that allows
lifting control operations of type:
(b a -> b a) to: (.
MonadBaseControl b m => m a -> m a)
For example:
liftBaseOp_ mask_ ::MonadBaseControlIOm => m a -> m a
liftBaseDiscard :: MonadBaseControl b m => (b () -> b α) -> m () -> m αSource
liftBaseDiscard is a particular application of liftBaseWith that allows
lifting control operations of type:
(b () -> b a) to: (.
MonadBaseControl b m => m () -> m a)
Note that, while the argument computation m () has access to the captured
state, all its side-effects in m are discarded. It is run only for its
side-effects in the base monad b.
For example:
liftBaseDiscard forkIO ::MonadBaseControlIOm => m () -> m ThreadId