-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Lift control operations, like exception catching, through monad transformers
--   
--   This package defines the type class <tt>MonadBaseControl</tt>, a
--   subset of <tt>MonadBase</tt> into which generic control operations
--   such as <tt>catch</tt> can be lifted from <tt>IO</tt> or any other
--   base monad. Instances are based on monad transformers in
--   <tt>MonadTransControl</tt>, which includes all standard monad
--   transformers in the <tt>transformers</tt> library except
--   <tt>ContT</tt>.
--   
--   See the <tt>lifted-base</tt> package which uses <tt>monad-control</tt>
--   to lift <tt>IO</tt> operations from the <tt>base</tt> library (like
--   <tt>catch</tt> or <tt>bracket</tt>) into any monad that is an instance
--   of <tt>MonadBase</tt> or <tt>MonadBaseControl</tt>.
--   
--   Note that this package is a rewrite of Anders Kaseorg's
--   <tt>monad-peel</tt> library. The main difference is that this package
--   provides CPS style operators and exploits the <tt>RankNTypes</tt> and
--   <tt>TypeFamilies</tt> language extensions to simplify and speedup most
--   definitions.
--   
--   The following <tt>criterion</tt> based benchmark shows that
--   <tt>monad-control</tt> is on average about 99% faster than
--   <tt>monad-peel</tt>:
--   
--   <pre>
--   git clone <a>https://github.com/basvandijk/bench-monad-peel-control</a>
--   </pre>
@package monad-control
@version 0.3.2.1


-- | (TODO: It would be nicer if the associated <i>data types</i>
--   <a>StT</a> and <a>StM</a> were associated <i>type synonyms</i>
--   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: <a>http://hackage.haskell.org/trac/ghc/ticket/5595</a>.
--   I will switch to associated type synonyms when that bug is fixed.)
module Control.Monad.Trans.Control
class MonadTrans t => MonadTransControl t where data family StT t :: * -> *
liftWith :: (MonadTransControl t, Monad m) => (Run t -> m a) -> t m a
restoreT :: (MonadTransControl t, Monad m) => m (StT t a) -> t m a

-- | A function that runs a transformed monad <tt>t n</tt> on the monadic
--   state that was captured by <a>liftWith</a>
--   
--   A <tt>Run t</tt> function yields a computation in <tt>n</tt> that
--   returns the monadic state of <tt>t</tt>. This state can later be used
--   to restore a <tt>t</tt> computation using <a>restoreT</a>.
type Run t = forall n b. Monad n => t n b -> n (StT t b)

-- | Default definition for the <a>liftWith</a> method.
defaultLiftWith :: (Monad m, MonadTransControl n) => (forall b. n m b -> t m b) -> (forall o b. t o b -> n o b) -> (forall b. StT n b -> StT t b) -> (Run t -> m a) -> t m a
defaultRestoreT :: (Monad m, MonadTransControl n) => (n m a -> t m a) -> (StT t a -> StT n a) -> m (StT t a) -> t m a
class MonadBase b m => MonadBaseControl b m | m -> b where data family StM m :: * -> *
liftBaseWith :: MonadBaseControl b m => (RunInBase m b -> b a) -> m a
restoreM :: MonadBaseControl b m => StM m a -> m a

-- | A function that runs a <tt>m</tt> computation on the monadic state
--   that was captured by <a>liftBaseWith</a>
--   
--   A <tt>RunInBase m</tt> function yields a computation in the base monad
--   of <tt>m</tt> that returns the monadic state of <tt>m</tt>. This state
--   can later be used to restore the <tt>m</tt> computation using
--   <a>restoreM</a>.
type RunInBase m b = forall a. m a -> b (StM m a)

-- | Handy type synonym that composes the monadic states of <tt>t</tt> and
--   <tt>m</tt>.
--   
--   It can be used to define the <a>StM</a> for new
--   <a>MonadBaseControl</a> instances.
type ComposeSt t m a = StM m (StT t a)

-- | Default defintion for the <a>liftBaseWith</a> method.
--   
--   Note that it composes a <a>liftWith</a> of <tt>t</tt> with a
--   <a>liftBaseWith</a> of <tt>m</tt> to give a <a>liftBaseWith</a> of
--   <tt>t m</tt>:
--   
--   <pre>
--   defaultLiftBaseWith stM = \f -&gt; <a>liftWith</a> $ \run -&gt;
--                                     <a>liftBaseWith</a> $ \runInBase -&gt;
--                                       f $ liftM stM . runInBase . run
--   </pre>
defaultLiftBaseWith :: (MonadTransControl t, MonadBaseControl b m) => (forall c. ComposeSt t m c -> StM (t m) c) -> ((RunInBase (t m) b -> b a) -> t m a)

-- | Default definition for the <a>restoreM</a> method.
--   
--   Note that: <tt>defaultRestoreM unStM = <a>restoreT</a> .
--   <a>restoreM</a> . unStM</tt>
defaultRestoreM :: (MonadTransControl t, MonadBaseControl b m) => (StM (t m) a -> ComposeSt t m a) -> (StM (t m) a -> t m a)

-- | An often used composition: <tt>control f = <a>liftBaseWith</a> f
--   &gt;&gt;= <a>restoreM</a></tt>
control :: MonadBaseControl b m => (RunInBase m b -> b (StM m a)) -> m a

-- | <tt>liftBaseOp</tt> is a particular application of <a>liftBaseWith</a>
--   that allows lifting control operations of type:
--   
--   <tt>((a -&gt; b c) -&gt; b c)</tt> to: <tt>(<a>MonadBaseControl</a> b
--   m =&gt; (a -&gt; m c) -&gt; m c)</tt>.
--   
--   For example:
--   
--   <pre>
--   liftBaseOp alloca :: <a>MonadBaseControl</a> <a>IO</a> m =&gt; (Ptr a -&gt; m c) -&gt; m c
--   </pre>
liftBaseOp :: MonadBaseControl b m => ((a -> b (StM m c)) -> b (StM m d)) -> ((a -> m c) -> m d)

-- | <tt>liftBaseOp_</tt> is a particular application of
--   <a>liftBaseWith</a> that allows lifting control operations of type:
--   
--   <tt>(b a -&gt; b a)</tt> to: <tt>(<a>MonadBaseControl</a> b m =&gt; m
--   a -&gt; m a)</tt>.
--   
--   For example:
--   
--   <pre>
--   liftBaseOp_ mask_ :: <a>MonadBaseControl</a> <a>IO</a> m =&gt; m a -&gt; m a
--   </pre>
liftBaseOp_ :: MonadBaseControl b m => (b (StM m a) -> b (StM m c)) -> (m a -> m c)

-- | <tt>liftBaseDiscard</tt> is a particular application of
--   <a>liftBaseWith</a> that allows lifting control operations of type:
--   
--   <tt>(b () -&gt; b a)</tt> to: <tt>(<a>MonadBaseControl</a> b m =&gt; m
--   () -&gt; m a)</tt>.
--   
--   Note that, while the argument computation <tt>m ()</tt> has access to
--   the captured state, all its side-effects in <tt>m</tt> are discarded.
--   It is run only for its side-effects in the base monad <tt>b</tt>.
--   
--   For example:
--   
--   <pre>
--   liftBaseDiscard forkIO :: <a>MonadBaseControl</a> <a>IO</a> m =&gt; m () -&gt; m ThreadId
--   </pre>
liftBaseDiscard :: MonadBaseControl b m => (b () -> b a) -> (m () -> m a)
instance (Monoid w, MonadBaseControl b m) => MonadBaseControl b (RWST r w s m)
instance (Monoid w, MonadBaseControl b m) => MonadBaseControl b (RWST r w s m)
instance (Monoid w, MonadBaseControl b m) => MonadBaseControl b (WriterT w m)
instance (Monoid w, MonadBaseControl b m) => MonadBaseControl b (WriterT w m)
instance (Error e, MonadBaseControl b m) => MonadBaseControl b (ErrorT e m)
instance MonadBaseControl b m => MonadBaseControl b (StateT s m)
instance MonadBaseControl b m => MonadBaseControl b (StateT s m)
instance MonadBaseControl b m => MonadBaseControl b (ReaderT r m)
instance MonadBaseControl b m => MonadBaseControl b (ListT m)
instance MonadBaseControl b m => MonadBaseControl b (MaybeT m)
instance MonadBaseControl b m => MonadBaseControl b (IdentityT m)
instance MonadBaseControl (ST s) (ST s)
instance MonadBaseControl (ST s) (ST s)
instance MonadBaseControl STM STM
instance MonadBaseControl Identity Identity
instance MonadBaseControl ((->) r) ((->) r)
instance MonadBaseControl [] []
instance MonadBaseControl (Either e) (Either e)
instance MonadBaseControl Maybe Maybe
instance MonadBaseControl IO IO
instance Monoid w => MonadTransControl (RWST r w s)
instance Monoid w => MonadTransControl (RWST r w s)
instance Monoid w => MonadTransControl (WriterT w)
instance Monoid w => MonadTransControl (WriterT w)
instance MonadTransControl (StateT s)
instance MonadTransControl (StateT s)
instance MonadTransControl (ReaderT r)
instance MonadTransControl ListT
instance Error e => MonadTransControl (ErrorT e)
instance MonadTransControl MaybeT
instance MonadTransControl IdentityT
