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


-- | Lift control operations like exception catching through monad transformers
--   
--   This package defines <tt>MonadPeelIO</tt>, a subset of
--   <tt>MonadIO</tt> into which generic control operations such as
--   <tt>catch</tt> can be lifted from <tt>IO</tt>. Instances are based on
--   monad transformers in <tt>MonadTransPeel</tt>, which includes all
--   standard monad transformers in the <tt>transformers</tt> library
--   except <tt>ContT</tt>. For convenience, it provides a wrapped version
--   of Control.Exception with types generalized from <tt>IO</tt> to all
--   monads in <tt>MonadPeelIO</tt>.
@package monad-peel
@version 0.2.1.2


-- | This module defines the class <a>MonadTransPeel</a> of monad
--   transformers through which control operations can be lifted. Instances
--   are included for all the standard monad transformers from the
--   <tt>transformers</tt> library except <tt>ContT</tt>.
--   
--   <a>idPeel</a> and <a>liftPeel</a> are provided to assist creation of
--   <tt>MonadPeelIO</tt>-like classes (see <a>Control.Monad.IO.Peel</a>)
--   based on core monads other than <a>IO</a>.
--   
--   <a>liftOp</a> and <a>liftOp_</a> enable convenient lifting of two
--   common special cases of control operation types.
module Control.Monad.Trans.Peel

-- | <tt>MonadTransPeel</tt> is the class of monad transformers supporting
--   an extra operation <a>peel</a>, enabling control operations (functions
--   that use monadic actions as input instead of just output) to be lifted
--   through the transformer.
class MonadTrans t => MonadTransPeel t

-- | <tt>peel</tt> is used to peel off the outer layer of a transformed
--   monadic action, allowing an transformed action <tt>t m a</tt> to be
--   treated as a base action <tt>m b</tt>.
--   
--   More precisely, <tt>peel</tt> captures the monadic state of <tt>t</tt>
--   at the point where it is bound (in <tt>t n</tt>), yielding a function
--   <tt>t m a -&gt; m (t o a)</tt>; this function runs a transformed
--   monadic action <tt>t m a</tt> in the base monad <tt>m</tt> using the
--   captured state, and leaves the result <tt>t o a</tt> in the monad
--   <tt>m</tt> after all side effects in <tt>m</tt> have occurred.
--   
--   This can be used together with <a>lift</a> to lift control operations
--   with types such as <tt>M a -&gt; M a</tt> into the transformed monad
--   <tt>t M</tt>:
--   
--   <pre>
--   instance Monad M
--   foo :: M a -&gt; M a
--   foo' :: (<a>MonadTransPeel</a> t, <a>Monad</a> (t M)) =&gt; t M a -&gt; t M a
--   foo' a = do
--     k &lt;- <a>peel</a>  -- k :: t M a -&gt; M (t M a)
--     <a>join</a> $ <a>lift</a> $ foo (k a)  -- uses foo :: M (t M a) -&gt; M (t M a)
--   </pre>
--   
--   <tt>peel</tt> is typically used with <tt>m == n == o</tt>, but is
--   required to be polymorphic for greater type safety: for example, this
--   type ensures that the result of running the action in <tt>m</tt> has
--   no remaining side effects in <tt>m</tt>.
peel :: (MonadTransPeel t, Monad m, Monad n, Monad o) => t n (t m a -> m (t o a))

-- | <tt>idPeel</tt> acts as the "identity" <a>peel</a> operation from a
--   monad <tt>m</tt> to itself.
--   
--   <pre>
--   <a>idPeel</a> = <a>return</a> $ <a>liftM</a> <a>return</a>
--   </pre>
--   
--   It serves as the base case for a class like <tt>MonadPeelIO</tt>,
--   which allows control operations in some base monad (here <tt>IO</tt>)
--   to be lifted through arbitrary stacks of zero or more monad
--   transformers in one call. For example, <a>Control.Monad.IO.Peel</a>
--   defines
--   
--   <pre>
--   class <tt>MonadIO</tt> m =&gt; MonadPeelIO m where
--     peelIO :: m (m a -&gt; <a>IO</a> (m a))
--   instance MonadPeelIO <a>IO</a> where
--     peelIO = <a>idPeel</a>
--   </pre>
idPeel :: (Monad m, Monad n, Monad o) => n (m a -> m (o a))

-- | <tt>liftPeel</tt> is used to compose two <a>peel</a> operations: the
--   outer provided by a <a>MonadTransPeel</a> instance, and the inner
--   provided as the argument.
--   
--   It satisfies <tt><a>liftPeel</a> <a>idPeel</a> == <a>peel</a></tt>.
--   
--   It serves as the induction step of a <tt>MonadPeelIO</tt>-like class.
--   For example, <a>Control.Monad.IO.Peel</a> defines
--   
--   <pre>
--   instance MonadPeelIO m =&gt; MonadPeelIO (<a>StateT</a> s m) where
--     peelIO = <a>liftPeel</a> peelIO
--   </pre>
--   
--   using the <a>MonadTransPeel</a> instance of <tt><a>StateT</a> s</tt>.
liftPeel :: (MonadTransPeel t, Monad m, Monad m', Monad n', Monad (t n'), Monad o', Monad (t o')) => n' (m' (t o' a) -> m (o' (t o' a))) -> t n' (t m' a -> m (t o' a))

-- | <tt>liftOp</tt> is a particular application of <a>peel</a> that allows
--   lifting control operations of type <tt>(a -&gt; m b) -&gt; m b</tt> to
--   <tt><a>MonadTransPeel</a> t =&gt; (a -&gt; t m b) -&gt; t m b</tt>.
--   
--   <pre>
--   <a>liftOp</a> f g = do
--     k &lt;- <a>peel</a>
--     <a>join</a> $ <a>lift</a> $ f (k . g)
--   </pre>
liftOp :: (MonadTransPeel t, Monad m, Monad n, Monad o, Monad (t n)) => ((a -> m (t o b)) -> n (t n c)) -> (a -> t m b) -> t n c

-- | <tt>liftOp_</tt> is a particular application of <a>peel</a> that
--   allows lifting control operations of type <tt>m a -&gt; m a</tt> to
--   <tt><a>MonadTransPeel</a> m =&gt; t m a -&gt; t m a</tt>.
--   
--   It can be thought of as a generalization of <tt>mapReaderT</tt>,
--   <tt>mapStateT</tt>, etc.
--   
--   <pre>
--   <a>liftOp_</a> f m = do
--     k &lt;- <a>peel</a>
--     <a>join</a> $ <a>lift</a> $ f (k m)
--   </pre>
liftOp_ :: (MonadTransPeel t, Monad m, Monad n, Monad o, Monad (t n)) => (m (t o a) -> n (t n b)) -> t m a -> t n b
instance Control.Monad.Trans.Peel.MonadTransPeel Control.Monad.Trans.Identity.IdentityT
instance Control.Monad.Trans.Peel.MonadTransPeel Control.Monad.Trans.List.ListT
instance Control.Monad.Trans.Peel.MonadTransPeel Control.Monad.Trans.Maybe.MaybeT
instance Control.Monad.Trans.Error.Error e => Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.Error.ErrorT e)
instance Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.Except.ExceptT e)
instance Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.Reader.ReaderT r)
instance Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.State.Lazy.StateT s)
instance Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.State.Strict.StateT s)
instance GHC.Base.Monoid w => Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.Writer.Lazy.WriterT w)
instance GHC.Base.Monoid w => Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.Writer.Strict.WriterT w)
instance GHC.Base.Monoid w => Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.RWS.Lazy.RWST r w s)
instance GHC.Base.Monoid w => Control.Monad.Trans.Peel.MonadTransPeel (Control.Monad.Trans.RWS.Strict.RWST r w s)


-- | This module defines the class <a>MonadPeelIO</a> of <a>IO</a>-based
--   monads into which control operations on <a>IO</a> (such as exception
--   catching; see <a>Control.Exception.Peel</a>) can be lifted.
--   
--   <a>liftIOOp</a> and <a>liftIOOp_</a> enable convenient lifting of two
--   common special cases of control operation types.
module Control.Monad.IO.Peel

-- | <tt>MonadPeelIO</tt> is the class of <a>IO</a>-based monads supporting
--   an extra operation <a>peelIO</a>, enabling control operations on
--   <a>IO</a> to be lifted into the monad.
class MonadIO m => MonadPeelIO m

-- | <tt>peelIO</tt> is a version of <a>peel</a> that operates through an
--   arbitrary stack of monad transformers directly to an inner <a>IO</a>
--   (analagously to how <a>liftIO</a> is a version of <tt>lift</tt>). So
--   it can be used with <a>liftIO</a> to lift control operations on
--   <a>IO</a> into any monad in <a>MonadPeelIO</a>. For example:
--   
--   <pre>
--   foo :: <a>IO</a> a -&gt; <a>IO</a> a
--   foo' :: <a>MonadPeelIO</a> m =&gt; m a -&gt; m a
--   foo' a = do
--     k &lt;- <a>peelIO</a>  -- k :: m a -&gt; IO (m a)
--     <a>join</a> $ <a>liftIO</a> $ foo (k a)  -- uses foo :: <a>IO</a> (m a) -&gt; <a>IO</a> (m a)
--   </pre>
--   
--   Note that the "obvious" term of this type (<tt>peelIO = <a>return</a>
--   <a>return</a></tt>) <i>does not</i> work correctly. Instances of
--   <a>MonadPeelIO</a> should be constructed via <a>MonadTransPeel</a>,
--   using <tt>peelIO = <a>liftPeel</a> peelIO</tt>.
peelIO :: MonadPeelIO m => m (m a -> IO (m a))

-- | <tt>liftIOOp</tt> is a particular application of <a>peelIO</a> that
--   allows lifting control operations of type <tt>(a -&gt; <a>IO</a> b)
--   -&gt; <a>IO</a> b</tt> (e.g. <tt>alloca</tt>, <tt>withMVar v</tt>) to
--   <tt><a>MonadPeelIO</a> m =&gt; (a -&gt; m b) -&gt; m b</tt>.
--   
--   <pre>
--   <a>liftIOOp</a> f g = do
--     k &lt;- <a>peelIO</a>
--     <a>join</a> $ <a>liftIO</a> $ f (k . g)
--   </pre>
liftIOOp :: MonadPeelIO m => ((a -> IO (m b)) -> IO (m c)) -> (a -> m b) -> m c

-- | <tt>liftIOOp_</tt> is a particular application of <a>peelIO</a> that
--   allows lifting control operations of type <tt><a>IO</a> a -&gt;
--   <a>IO</a> a</tt> (e.g. <tt>block</tt>) to <tt><a>MonadPeelIO</a> m
--   =&gt; m a -&gt; m a</tt>.
--   
--   <pre>
--   <a>liftIOOp_</a> f m = do
--     k &lt;- <a>peelIO</a>
--     <a>join</a> $ <a>liftIO</a> $ f (k m)
--   </pre>
liftIOOp_ :: MonadPeelIO m => (IO (m a) -> IO (m b)) -> m a -> m b
instance Control.Monad.IO.Peel.MonadPeelIO GHC.Types.IO
instance Control.Monad.IO.Peel.MonadPeelIO m => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.Identity.IdentityT m)
instance Control.Monad.IO.Peel.MonadPeelIO m => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.List.ListT m)
instance Control.Monad.IO.Peel.MonadPeelIO m => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.Maybe.MaybeT m)
instance (Control.Monad.Trans.Error.Error e, Control.Monad.IO.Peel.MonadPeelIO m) => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.Error.ErrorT e m)
instance Control.Monad.IO.Peel.MonadPeelIO m => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.Except.ExceptT e m)
instance Control.Monad.IO.Peel.MonadPeelIO m => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.Reader.ReaderT r m)
instance Control.Monad.IO.Peel.MonadPeelIO m => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.State.Lazy.StateT s m)
instance Control.Monad.IO.Peel.MonadPeelIO m => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.State.Strict.StateT s m)
instance (GHC.Base.Monoid w, Control.Monad.IO.Peel.MonadPeelIO m) => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (GHC.Base.Monoid w, Control.Monad.IO.Peel.MonadPeelIO m) => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.Writer.Strict.WriterT w m)
instance (GHC.Base.Monoid w, Control.Monad.IO.Peel.MonadPeelIO m) => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (GHC.Base.Monoid w, Control.Monad.IO.Peel.MonadPeelIO m) => Control.Monad.IO.Peel.MonadPeelIO (Control.Monad.Trans.RWS.Strict.RWST r w s m)


-- | This is a wrapped version of Control.Exception with types generalized
--   from <a>IO</a> to all monads in <a>MonadPeelIO</a>.
module Control.Exception.Peel

-- | Generalized version of <a>throwIO</a>.
throwIO :: (MonadIO m, Exception e) => e -> m a

-- | Generalized version of <a>ioError</a>.
ioError :: MonadIO m => IOError -> m a

-- | Generalized version of <a>catch</a>.
catch :: (MonadPeelIO m, Exception e) => m a -> (e -> m a) -> m a

-- | Generalized version of <a>catches</a>.
catches :: MonadPeelIO m => m a -> [Handler m a] -> m a

-- | Generalized version of <a>Handler</a>.
data Handler m a
Handler :: (e -> m a) -> Handler m a

-- | Generalized version of <a>catchJust</a>.
catchJust :: (MonadPeelIO m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a

-- | Generalized version of <a>handle</a>.
handle :: (MonadPeelIO m, Exception e) => (e -> m a) -> m a -> m a

-- | Generalized version of <a>handleJust</a>.
handleJust :: (MonadPeelIO m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a

-- | Generalized version of <a>try</a>.
try :: (MonadPeelIO m, Exception e) => m a -> m (Either e a)

-- | Generalized version of <a>tryJust</a>.
tryJust :: (MonadPeelIO m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)

-- | Generalized version of <a>evaluate</a>.
evaluate :: MonadIO m => a -> m a

-- | Generalized version of <a>bracket</a>. Note, any monadic side effects
--   in <tt>m</tt> of the "release" computation will be discarded; it is
--   run only for its side effects in <tt>IO</tt>.
bracket :: MonadPeelIO m => m a -> (a -> m b) -> (a -> m c) -> m c

-- | Generalized version of <a>bracket_</a>. Note, any monadic side effects
--   in <tt>m</tt> of <i>both</i> the "acquire" and "release" computations
--   will be discarded. To keep the monadic side effects of the "acquire"
--   computation, use <a>bracket</a> with constant functions instead.
bracket_ :: MonadPeelIO m => m a -> m b -> m c -> m c

-- | Generalized version of <a>bracketOnError</a>.
bracketOnError :: MonadPeelIO m => m a -> (a -> m b) -> (a -> m c) -> m c

-- | Generalized version of <a>finally</a>. Note, any monadic side effects
--   in <tt>m</tt> of the "afterward" computation will be discarded.
finally :: MonadPeelIO m => m a -> m b -> m a

-- | Generalized version of <a>onException</a>.
onException :: MonadPeelIO m => m a -> m b -> m a
