monad-control-1.0.3.1: Lift control operations, like exception catching, through monad transformers
CopyrightBas van Dijk Anders Kaseorg
LicenseBSD3
MaintainerBas van Dijk <v.dijk.bas@gmail.com>
Safe HaskellSafe
LanguageHaskell2010

Control.Monad.Trans.Control

Description

This module defines the type class MonadBaseControl, a subset of MonadBase into which generic control operations such as catch can be lifted from IO or any other base monad. Instances are based on monad transformers in MonadTransControl, which includes all standard monad transformers in the transformers library except ContT.

See the lifted-base package which uses monad-control to lift IO operations from the base library (like catch or bracket) into any monad that is an instance of MonadBase or MonadBaseControl.

See the following tutorial by Michael Snoyman on how to use this package:

https://www.yesodweb.com/book/monad-control

Quick implementation guide

Given a base monad B and a stack of transformers T:

Synopsis

MonadTransControl

class MonadTrans t => MonadTransControl t where Source #

The MonadTransControl type class is a stronger version of MonadTrans:

Instances of MonadTrans know how to lift actions in the base monad to the transformed monad. These lifted actions, however, are completely unaware of the monadic state added by the transformer.

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 withFile. MonadTransControl 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 StT t a :: * Source #

Monadic state of t.

The monadic state of a monad transformer is the result type of its run function, 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 a

Provided type instances:

StT IdentityT    a ~ a
StT MaybeT       a ~ Maybe a
StT (ErrorT e)   a ~ Error e => Either e a
StT (ExceptT e)  a ~ Either e a
StT ListT        a ~ [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 a 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 (\_ -> return a) = return a
liftWith (\_ -> m >>= f)  =  liftWith (\_ -> m) >>= (\a -> liftWith (\_ -> f a))

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, 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 . return

If the Run function is ignored, liftWith coincides with lift:

lift f = liftWith (\_ -> f)

Implementations use the Run function 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 (liftM Just (f runMaybeT))

restoreT :: Monad m => m (StT t a) -> t m a 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

restoreT is 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 action

Example type signatures:

restoreT :: Monad m             => m a            -> IdentityT m a
restoreT :: Monad m             => m (Maybe a)    -> MaybeT m a
restoreT :: (Monad m, Error e)  => m (Either e a) -> ErrorT e m a
restoreT :: Monad m             => m (Either e a) -> ExceptT e m a
restoreT :: Monad m             => m [a]          -> ListT m 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

Instances

Instances details
MonadTransControl ListT Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT ListT a Source #

Methods

liftWith :: Monad m => (Run ListT -> m a) -> ListT m a Source #

restoreT :: Monad m => m (StT ListT a) -> ListT m a Source #

MonadTransControl MaybeT Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT MaybeT a Source #

Methods

liftWith :: Monad m => (Run MaybeT -> m a) -> MaybeT m a Source #

restoreT :: Monad m => m (StT MaybeT a) -> MaybeT m a Source #

Error e => MonadTransControl (ErrorT e) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (ErrorT e) a Source #

Methods

liftWith :: Monad m => (Run (ErrorT e) -> m a) -> ErrorT e m a Source #

restoreT :: Monad m => m (StT (ErrorT e) a) -> ErrorT e m a Source #

MonadTransControl (ExceptT e) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (ExceptT e) a Source #

Methods

liftWith :: Monad m => (Run (ExceptT e) -> m a) -> ExceptT e m a Source #

restoreT :: Monad m => m (StT (ExceptT e) a) -> ExceptT e m a Source #

MonadTransControl (IdentityT :: (Type -> Type) -> Type -> Type) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT IdentityT a Source #

Methods

liftWith :: Monad m => (Run IdentityT -> m a) -> IdentityT m a Source #

restoreT :: Monad m => m (StT IdentityT a) -> IdentityT m a Source #

MonadTransControl (ReaderT r) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (ReaderT r) a Source #

Methods

liftWith :: Monad m => (Run (ReaderT r) -> m a) -> ReaderT r m a Source #

restoreT :: Monad m => m (StT (ReaderT r) a) -> ReaderT r m a Source #

MonadTransControl (StateT s) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (StateT s) a Source #

Methods

liftWith :: Monad m => (Run (StateT s) -> m a) -> StateT s m a Source #

restoreT :: Monad m => m (StT (StateT s) a) -> StateT s m a Source #

MonadTransControl (StateT s) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (StateT s) a Source #

Methods

liftWith :: Monad m => (Run (StateT s) -> m a) -> StateT s m a Source #

restoreT :: Monad m => m (StT (StateT s) a) -> StateT s m a Source #

Monoid w => MonadTransControl (WriterT w) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (WriterT w) a Source #

Methods

liftWith :: Monad m => (Run (WriterT w) -> m a) -> WriterT w m a Source #

restoreT :: Monad m => m (StT (WriterT w) a) -> WriterT w m a Source #

Monoid w => MonadTransControl (WriterT w) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (WriterT w) a Source #

Methods

liftWith :: Monad m => (Run (WriterT w) -> m a) -> WriterT w m a Source #

restoreT :: Monad m => m (StT (WriterT w) a) -> WriterT w m a Source #

Monoid w => MonadTransControl (RWST r w s) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (RWST r w s) a Source #

Methods

liftWith :: Monad m => (Run (RWST r w s) -> m a) -> RWST r w s m a Source #

restoreT :: Monad m => m (StT (RWST r w s) a) -> RWST r w s m a Source #

Monoid w => MonadTransControl (RWST r w s) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StT (RWST r w s) a Source #

Methods

liftWith :: Monad m => (Run (RWST r w s) -> m a) -> RWST r w s m a Source #

restoreT :: Monad m => m (StT (RWST r w s) a) -> RWST r w s m a Source #

type Run t = forall n b. Monad n => t n b -> n (StT t b) Source #

A function that runs a transformed monad t n on the monadic state that was captured by liftWith

A Run t function yields a computation in n that returns the monadic state of t. This state can later be used to restore a t computation using restoreT.

Example type equalities:

Run IdentityT    ~ forall n b. Monad n             => IdentityT  n b -> n b
Run MaybeT       ~ forall n b. Monad n             => MaybeT     n b -> n (Maybe b)
Run (ErrorT e)   ~ forall n b. (Monad n, Error e)  => ErrorT e   n b -> n (Either e b)
Run (ExceptT e)  ~ forall n b. Monad n             => ExceptT e  n b -> n (Either e b)
Run ListT        ~ forall n b. Monad n             => ListT      n b -> n [b]
Run (ReaderT r)  ~ forall n b. Monad n             => ReaderT r  n b -> n b
Run (StateT s)   ~ forall n b. Monad n             => StateT s   n b -> n (a, s)
Run (WriterT w)  ~ forall n b. (Monad n, Monoid w) => WriterT w  n b -> n (a, w)
Run (RWST r w s) ~ forall n b. (Monad n, Monoid w) => RWST r w s n b -> n (a, s, w)

This type is usually satisfied by the run function of a transformer:

flip runReaderT :: r -> Run (ReaderT r)
flip runStateT  :: s -> Run (StateT s)
runMaybeT       ::      Run MaybeT

Defaults

The following functions can be used to define a MonadTransControl instance for a monad transformer which simply is a newtype around another monad transformer which already has a MonadTransControl instance. For example:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeFamilies #-}

newtype CounterT m a = CounterT {unCounterT :: StateT Int m a}
  deriving (Monad, MonadTrans)

instance MonadTransControl CounterT where
    type StT CounterT a = StT (StateT Int) a
    liftWith = defaultLiftWith CounterT unCounterT
    restoreT = defaultRestoreT CounterT

type RunDefault t t' = forall n b. Monad n => t n b -> n (StT t' b) Source #

A function like Run that runs a monad transformer t which wraps the monad transformer t'. This is used in defaultLiftWith.

defaultLiftWith Source #

Arguments

:: (Monad m, MonadTransControl n) 
=> (forall b. n m b -> t m b)

Monad constructor

-> (forall o b. t o b -> n o b)

Monad deconstructor

-> (RunDefault t n -> m a) 
-> t m a 

Default definition for the liftWith method.

defaultRestoreT Source #

Arguments

:: (Monad m, MonadTransControl n) 
=> (n m a -> t m a)

Monad constructor

-> m (StT n a) 
-> t m a 

Default definition for the restoreT method.

Defaults for a stack of two

The following functions can be used to define a MonadTransControl instance for a monad transformer stack of two.

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype CalcT m a = CalcT { unCalcT :: StateT Int (ExceptT String m) a }
  deriving (Monad, MonadTrans)

instance MonadTransControl CalcT where
    type StT CalcT a = StT (ExceptT String) (StT (StateT Int) a)
    liftWith = defaultLiftWith2 CalcT unCalcT
    restoreT = defaultRestoreT2 CalcT

type RunDefault2 t n n' = forall m b. (Monad m, Monad (n' m)) => t m b -> m (StT n' (StT n b)) Source #

A function like Run that runs a monad transformer t which wraps the monad transformers n and n'. This is used in defaultLiftWith2.

defaultLiftWith2 Source #

Arguments

:: (Monad m, Monad (n' m), MonadTransControl n, MonadTransControl n') 
=> (forall b. n (n' m) b -> t m b)

Monad constructor

-> (forall o b. t o b -> n (n' o) b)

Monad deconstructor

-> (RunDefault2 t n n' -> m a) 
-> t m a 

Default definition for the liftWith method.

defaultRestoreT2 Source #

Arguments

:: (Monad m, Monad (n' m), MonadTransControl n, MonadTransControl n') 
=> (n (n' m) a -> t m a)

Monad constructor

-> m (StT n' (StT n a)) 
-> t m a 

Default definition for the restoreT method for double MonadTransControl.

MonadBaseControl

class MonadBase b m => MonadBaseControl b m | m -> b where Source #

Writing instances

The usual way to write a MonadBaseControl instance for a transformer stack over a base monad B is to write an instance MonadBaseControl B B for the base monad, and MonadTransControl T instances for every transformer T. Instances for MonadBaseControl are then simply implemented using ComposeSt, defaultLiftBaseWith, defaultRestoreM.

Associated Types

type StM m a :: * Source #

Monadic state that m adds to the base monad b.

For all base (non-transformed) monads, StM m a ~ a:

StM IO         a ~ a
StM Maybe      a ~ a
StM (Either e) a ~ a
StM []         a ~ a
StM ((->) r)   a ~ a
StM Identity   a ~ a
StM STM        a ~ a
StM (ST s)     a ~ a

If m is a transformed monad, m ~ t b, StM is the monadic state of the transformer t (given by its StT from MonadTransControl). For a transformer stack, StM is defined recursively:

StM (IdentityT  m) a ~ ComposeSt IdentityT m a ~ StM m a
StM (MaybeT     m) a ~ ComposeSt MaybeT    m a ~ StM m (Maybe a)
StM (ErrorT e   m) a ~ ComposeSt ErrorT    m a ~ Error e => StM m (Either e a)
StM (ExceptT e  m) a ~ ComposeSt ExceptT   m a ~ StM m (Either e a)
StM (ListT      m) a ~ ComposeSt ListT     m a ~ StM m [a]
StM (ReaderT r  m) a ~ ComposeSt ReaderT   m a ~ StM m a
StM (StateT s   m) a ~ ComposeSt StateT    m a ~ StM m (a, s)
StM (WriterT w  m) a ~ ComposeSt WriterT   m a ~ Monoid w => StM m (a, w)
StM (RWST r w s m) a ~ ComposeSt RWST      m a ~ Monoid w => StM m (a, s, w)

Methods

liftBaseWith :: (RunInBase m b -> b a) -> m a 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 (\_ -> return a) = return a
liftBaseWith (\_ -> m >>= f)  =  liftBaseWith (\_ -> m) >>= (\a -> liftBaseWith (\_ -> f a))

As Li-yao Xia explains, parametricity guarantees that

f $ liftBaseWith q = liftBaseWith $ runInBase -> f $ q runInBase

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:

withFileLifted :: MonadBaseControl IO m => FilePath -> IOMode -> (Handle -> m a) -> m a
withFileLifted file mode action = liftBaseWith (\runInBase -> withFile file mode (runInBase . action)) >>= restoreM
                             -- = control $ \runInBase -> withFile file mode (runInBase . action)
                             -- = liftBaseOp (withFile file mode) action

liftBaseWith is usually not implemented directly, but using defaultLiftBaseWith.

restoreM :: StM m a -> m a 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

restoreM is usually not implemented directly, but using defaultRestoreM.

Instances

Instances details
MonadBaseControl Identity Identity Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM Identity a Source #

MonadBaseControl STM STM Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM STM a Source #

Methods

liftBaseWith :: (RunInBase STM STM -> STM a) -> STM a Source #

restoreM :: StM STM a -> STM a Source #

MonadBaseControl IO IO Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM IO a Source #

Methods

liftBaseWith :: (RunInBase IO IO -> IO a) -> IO a Source #

restoreM :: StM IO a -> IO a Source #

MonadBaseControl Maybe Maybe Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM Maybe a Source #

MonadBaseControl [] [] Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM [] a Source #

Methods

liftBaseWith :: (RunInBase [] [] -> [a]) -> [a] Source #

restoreM :: StM [] a -> [a] Source #

MonadBaseControl b m => MonadBaseControl b (ListT m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (ListT m) a Source #

Methods

liftBaseWith :: (RunInBase (ListT m) b -> b a) -> ListT m a Source #

restoreM :: StM (ListT m) a -> ListT m a Source #

MonadBaseControl b m => MonadBaseControl b (MaybeT m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (MaybeT m) a Source #

Methods

liftBaseWith :: (RunInBase (MaybeT m) b -> b a) -> MaybeT m a Source #

restoreM :: StM (MaybeT m) a -> MaybeT m a Source #

(Error e, MonadBaseControl b m) => MonadBaseControl b (ErrorT e m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (ErrorT e m) a Source #

Methods

liftBaseWith :: (RunInBase (ErrorT e m) b -> b a) -> ErrorT e m a Source #

restoreM :: StM (ErrorT e m) a -> ErrorT e m a Source #

MonadBaseControl b m => MonadBaseControl b (ExceptT e m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (ExceptT e m) a Source #

Methods

liftBaseWith :: (RunInBase (ExceptT e m) b -> b a) -> ExceptT e m a Source #

restoreM :: StM (ExceptT e m) a -> ExceptT e m a Source #

MonadBaseControl b m => MonadBaseControl b (IdentityT m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (IdentityT m) a Source #

Methods

liftBaseWith :: (RunInBase (IdentityT m) b -> b a) -> IdentityT m a Source #

restoreM :: StM (IdentityT m) a -> IdentityT m a Source #

MonadBaseControl b m => MonadBaseControl b (ReaderT r m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (ReaderT r m) a Source #

Methods

liftBaseWith :: (RunInBase (ReaderT r m) b -> b a) -> ReaderT r m a Source #

restoreM :: StM (ReaderT r m) a -> ReaderT r m a Source #

MonadBaseControl b m => MonadBaseControl b (StateT s m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (StateT s m) a Source #

Methods

liftBaseWith :: (RunInBase (StateT s m) b -> b a) -> StateT s m a Source #

restoreM :: StM (StateT s m) a -> StateT s m a Source #

MonadBaseControl b m => MonadBaseControl b (StateT s m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (StateT s m) a Source #

Methods

liftBaseWith :: (RunInBase (StateT s m) b -> b a) -> StateT s m a Source #

restoreM :: StM (StateT s m) a -> StateT s m a Source #

(Monoid w, MonadBaseControl b m) => MonadBaseControl b (WriterT w m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (WriterT w m) a Source #

Methods

liftBaseWith :: (RunInBase (WriterT w m) b -> b a) -> WriterT w m a Source #

restoreM :: StM (WriterT w m) a -> WriterT w m a Source #

(Monoid w, MonadBaseControl b m) => MonadBaseControl b (WriterT w m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (WriterT w m) a Source #

Methods

liftBaseWith :: (RunInBase (WriterT w m) b -> b a) -> WriterT w m a Source #

restoreM :: StM (WriterT w m) a -> WriterT w m a Source #

(Monoid w, MonadBaseControl b m) => MonadBaseControl b (RWST r w s m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (RWST r w s m) a Source #

Methods

liftBaseWith :: (RunInBase (RWST r w s m) b -> b a) -> RWST r w s m a Source #

restoreM :: StM (RWST r w s m) a -> RWST r w s m a Source #

(Monoid w, MonadBaseControl b m) => MonadBaseControl b (RWST r w s m) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (RWST r w s m) a Source #

Methods

liftBaseWith :: (RunInBase (RWST r w s m) b -> b a) -> RWST r w s m a Source #

restoreM :: StM (RWST r w s m) a -> RWST r w s m a Source #

MonadBaseControl (ST s) (ST s) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (ST s) a Source #

Methods

liftBaseWith :: (RunInBase (ST s) (ST s) -> ST s a) -> ST s a Source #

restoreM :: StM (ST s) a -> ST s a Source #

MonadBaseControl (Either e) (Either e) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (Either e) a Source #

Methods

liftBaseWith :: (RunInBase (Either e) (Either e) -> Either e a) -> Either e a Source #

restoreM :: StM (Either e) a -> Either e a Source #

MonadBaseControl (ST s) (ST s) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM (ST s) a Source #

Methods

liftBaseWith :: (RunInBase (ST s) (ST s) -> ST s a) -> ST s a Source #

restoreM :: StM (ST s) a -> ST s a Source #

MonadBaseControl ((->) r) ((->) r) Source # 
Instance details

Defined in Control.Monad.Trans.Control

Associated Types

type StM ((->) r) a Source #

Methods

liftBaseWith :: (RunInBase ((->) r) ((->) r) -> r -> a) -> r -> a Source #

restoreM :: StM ((->) r) a -> r -> a Source #

type RunInBase m b = forall a. m a -> b (StM m a) 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.

Example type equalities:

RunInBase (IdentityT  m) b ~ forall a.             IdentityT  m a -> b (StM m a)
RunInBase (MaybeT     m) b ~ forall a.             MaybeT     m a -> b (StM m (Maybe a))
RunInBase (ErrorT e   m) b ~ forall a. Error e =>  ErrorT e   m a -> b (StM m (Either e a))
RunInBase (ExceptT e  m) b ~ forall a.             ExceptT e  m a -> b (StM m (Either e a))
RunInBase (ListT      m) b ~ forall a.             ListT      m a -> b (StM m [a])
RunInBase (ReaderT r  m) b ~ forall a.             ReaderT    m a -> b (StM m a)
RunInBase (StateT s   m) b ~ forall a.             StateT s   m a -> b (StM m (a, s))
RunInBase (WriterT w  m) b ~ forall a. Monoid w => WriterT w  m a -> b (StM m (a, w))
RunInBase (RWST r w s m) b ~ forall a. Monoid w => RWST r w s m a -> b (StM m (a, s, w))

For a transformed base monad m ~ t b, 'RunInBase m b' ~ Run t.

Defaults

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
    type StM (T m) a = ComposeSt T m a
    liftBaseWith     = defaultLiftBaseWith
    restoreM         = defaultRestoreM

Defining an instance for a base monad B is equally straightforward:

instance MonadBaseControl B B where
    type StM B a   = a
    liftBaseWith f = f id
    restoreM       = return

type ComposeSt t m a = StM m (StT t a) 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.

type RunInBaseDefault t m b = forall a. t m a -> b (ComposeSt t m a) Source #

A function like RunInBase that runs a monad transformer t in its base monad b. It is used in defaultLiftBaseWith.

defaultLiftBaseWith :: (MonadTransControl t, MonadBaseControl b m) => (RunInBaseDefault t m b -> b a) -> t m a Source #

Default definition 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 = \f -> liftWith $ \run ->
                              liftBaseWith $ \runInBase ->
                                f $ runInBase . run

defaultRestoreM :: (MonadTransControl t, MonadBaseControl b m) => ComposeSt t m a -> t m a Source #

Default definition for the restoreM method.

Note that: defaultRestoreM = restoreT . restoreM

Utility functions

control :: MonadBaseControl b m => (RunInBase m b -> b (StM m a)) -> m a Source #

An often used composition: control f = liftBaseWith f >>= restoreM

Example:

liftedBracket :: MonadBaseControl IO m => m a -> (a -> m b) -> (a -> m c) -> m c
liftedBracket acquire release action = control $ \runInBase ->
    bracket (runInBase acquire)
            (\saved -> runInBase (restoreM saved >>= release))
            (\saved -> runInBase (restoreM saved >>= action))

controlT :: (MonadTransControl t, Monad (t m), Monad m) => (Run t -> m (StT t a)) -> t m a Source #

Lift a computation and restore the monadic state immediately: controlT f = liftWith f >>= restoreT . return.

embed :: MonadBaseControl b m => (a -> m c) -> m (a -> b (StM m c)) Source #

Embed a transformer function as an function in the base monad returning a mutated transformer state.

embed_ :: MonadBaseControl b m => (a -> m ()) -> m (a -> b ()) Source #

Performs the same function as embed, but discards transformer state from the embedded function.

captureT :: (MonadTransControl t, Monad (t m), Monad m) => t m (StT t ()) Source #

Capture the current state of a transformer

captureM :: MonadBaseControl b m => m (StM m ()) Source #

Capture the current state above the base monad

liftBaseOp :: MonadBaseControl b m => ((a -> b (StM m c)) -> b (StM m d)) -> (a -> m c) -> m d 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 :: (Storable a, MonadBaseControl IO m) => (Ptr a -> m c) -> m c

liftBaseOp_ :: MonadBaseControl b m => (b (StM m a) -> b (StM m c)) -> m a -> m c 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_ :: MonadBaseControl IO m => m a -> m a

liftBaseDiscard :: MonadBaseControl b m => (b () -> b a) -> m () -> m a 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 :: MonadBaseControl IO m => m () -> m ThreadId

liftBaseOpDiscard :: MonadBaseControl b m => ((a -> b ()) -> b c) -> (a -> m ()) -> m c Source #

liftBaseOpDiscard is a particular application of liftBaseWith that allows lifting control operations of type:

((a -> b ()) -> b c)

to:

(MonadBaseControl b m => (a -> m ()) -> m c)

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 (runServer addr port) :: MonadBaseControl IO m => m () -> m ()

liftThrough :: (MonadTransControl t, Monad (t m), Monad m) => (m (StT t a) -> m (StT t b)) -> t m a -> t m b Source #

Transform an action in t m using a transformer that operates on the underlying monad m