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


-- | Typeclasses for representing monad transformer unlifting
--   
--   See README.md
@package monad-unlift
@version 0.2.0


-- | See overview in the README.md
module Control.Monad.Trans.Unlift

-- | A monad transformer which can be unlifted, obeying the monad morphism
--   laws.
--   
--   Since 0.1.0
class (MonadTransControl t, Forall (Identical t)) => MonadTransUnlift t

-- | A function which can move an action down the monad transformer stack,
--   by providing any necessary environment to the action.
--   
--   Note that, if ImpredicativeTypes worked reliably, this type wouldn't
--   be necessary, and <a>askUnlift</a> would simply include a more
--   generalized type.
--   
--   Since 0.1.0
newtype Unlift t
Unlift :: (forall a n. Monad n => t n a -> n a) -> Unlift t
[unlift] :: Unlift t -> forall a n. Monad n => t n a -> n a

-- | Get the <a>Unlift</a> action for the current transformer layer.
--   
--   Since 0.1.0
askUnlift :: forall t m. (MonadTransUnlift t, Monad m) => t m (Unlift t)

-- | A simplified version of <a>askUnlift</a> which addresses the common
--   case where polymorphism isn't necessary.
--   
--   Since 0.1.0
askRun :: (MonadTransUnlift t, Monad (t m), Monad m) => t m (t m a -> m a)

-- | A monad transformer stack which can be unlifted, obeying the monad
--   morphism laws.
--   
--   Since 0.1.0
class (MonadBaseControl b m, Forall (IdenticalBase m)) => MonadBaseUnlift b m | m -> b

-- | Similar to <a>Unlift</a>, but instead of moving one layer down the
--   stack, moves the action to the base monad.
--   
--   Since 0.1.0
newtype UnliftBase b m
UnliftBase :: (forall a. m a -> b a) -> UnliftBase b m
[unliftBase] :: UnliftBase b m -> forall a. m a -> b a

-- | Get the <a>UnliftBase</a> action for the current transformer stack.
--   
--   Since 0.1.0
askUnliftBase :: forall b m. (MonadBaseUnlift b m) => m (UnliftBase b m)

-- | A simplified version of <a>askUnliftBase</a> which addresses the
--   common case where polymorphism isn't necessary.
--   
--   Since 0.1.0
askRunBase :: (MonadBaseUnlift b m) => m (m a -> b a)

-- | The class of monad transformers. Instances should satisfy the
--   following laws, which state that <a>lift</a> is a monad
--   transformation:
--   
--   <ul>
--   <li><pre><a>lift</a> . <a>return</a> = <a>return</a></pre></li>
--   <li><pre><a>lift</a> (m &gt;&gt;= f) = <a>lift</a> m &gt;&gt;=
--   (<a>lift</a> . f)</pre></li>
--   </ul>
class MonadTrans (t :: (* -> *) -> * -> *)

-- | Lift a computation from the argument monad to the constructed monad.
lift :: (MonadTrans t, Monad m) => m a -> t m a
class (Applicative b, Applicative m, Monad b, Monad m) => MonadBase (b :: * -> *) (m :: * -> *) | m -> b

-- | Lift a computation from the base monad
liftBase :: MonadBase b m => b α -> m α

-- | The <tt>MonadTransControl</tt> type class is a stronger version of
--   <tt><a>MonadTrans</a></tt>:
--   
--   Instances of <tt><a>MonadTrans</a></tt> know how to
--   <tt><tt>lift</tt></tt> actions in the base monad to the transformed
--   monad. These lifted actions, however, are completely unaware of the
--   monadic state added by the transformer.
--   
--   <tt><a>MonadTransControl</a></tt> 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
--   
--   <pre>
--   withFile :: FilePath -&gt; IOMode -&gt; (Handle -&gt; IO r) -&gt; IO r
--   </pre>
--   
--   <tt><a>MonadTrans</a></tt> instances can only lift the return type of
--   the <tt>withFile</tt> function:
--   
--   <pre>
--   withFileLifted :: MonadTrans t =&gt; FilePath -&gt; IOMode -&gt; (Handle -&gt; IO r) -&gt; t IO r
--   withFileLifted file mode action = lift (withFile file mode action)
--   </pre>
--   
--   However, <tt><a>MonadTrans</a></tt> is not powerful enough to make
--   <tt>withFileLifted</tt> accept a function that returns <tt>t IO</tt>.
--   The reason is that we need to take away the transformer layer in order
--   to pass the function to <tt><tt>withFile</tt></tt>.
--   <tt><a>MonadTransControl</a></tt> allows us to do this:
--   
--   <pre>
--   withFileLifted' :: (Monad (t IO), MonadTransControl t) =&gt; FilePath -&gt; IOMode -&gt; (Handle -&gt; t IO r) -&gt; t IO r
--   withFileLifted' file mode action = liftWith (\run -&gt; withFile file mode (run . action)) &gt;&gt;= restoreT . return
--   </pre>
class MonadTrans t => MonadTransControl (t :: (* -> *) -> * -> *) where type StT (t :: (* -> *) -> * -> *) a :: * where {
    type family StT (t :: (* -> *) -> * -> *) a :: *;
}

-- | <tt>liftWith</tt> is similar to <tt>lift</tt> in that it lifts a
--   computation from the argument monad to the constructed monad.
--   
--   Instances should satisfy similar laws as the <a>MonadTrans</a> laws:
--   
--   <pre>
--   liftWith . const . return = return
--   </pre>
--   
--   <pre>
--   liftWith (const (m &gt;&gt;= f)) = liftWith (const m) &gt;&gt;= liftWith . const . f
--   </pre>
--   
--   The difference with <tt>lift</tt> is that before lifting the
--   <tt>m</tt> computation <tt>liftWith</tt> captures the state of
--   <tt>t</tt>. It then provides the <tt>m</tt> computation with a
--   <a>Run</a> function that allows running <tt>t n</tt> computations in
--   <tt>n</tt> (for all <tt>n</tt>) on the captured state, e.g.
--   
--   <pre>
--   withFileLifted :: (Monad (t IO), MonadTransControl t) =&gt; FilePath -&gt; IOMode -&gt; (Handle -&gt; t IO r) -&gt; t IO r
--   withFileLifted file mode action = liftWith (\run -&gt; withFile file mode (run . action)) &gt;&gt;= restoreT . return
--   </pre>
--   
--   If the <tt>Run</tt> function is ignored, <tt>liftWith</tt> coincides
--   with <tt>lift</tt>:
--   
--   <pre>
--   lift f = liftWith (const f)
--   </pre>
--   
--   Implementations use the <tt><a>Run</a></tt> function associated with a
--   transformer:
--   
--   <pre>
--   liftWith :: <a>Monad</a> m =&gt; ((<a>Monad</a> n =&gt; <a>ReaderT</a> r n b -&gt; n b) -&gt; m a) -&gt; <a>ReaderT</a> r m a
--   liftWith f = <a>ReaderT</a> (r -&gt; f (action -&gt; <a>runReaderT</a> action r))
--   
--   liftWith :: <a>Monad</a> m =&gt; ((<a>Monad</a> n =&gt; <a>StateT</a> s n b -&gt; n (b, s)) -&gt; m a) -&gt; <a>StateT</a> s m a
--   liftWith f = <a>StateT</a> (s -&gt; <a>liftM</a> (x -&gt; (x, s)) (f (action -&gt; <a>runStateT</a> action s)))
--   
--   liftWith :: <a>Monad</a> m =&gt; ((<a>Monad</a> n =&gt; <a>MaybeT</a> n b -&gt; n (<a>Maybe</a> b)) -&gt; m a) -&gt; <a>MaybeT</a> m a
--   liftWith f = <a>MaybeT</a> (<a>liftM</a> <tt>Just</tt> (f <a>runMaybeT</a>))
--   </pre>
liftWith :: (MonadTransControl t, Monad m) => (Run t -> m a) -> t m a

-- | Construct a <tt>t</tt> computation from the monadic state of
--   <tt>t</tt> that is returned from a <a>Run</a> function.
--   
--   Instances should satisfy:
--   
--   <pre>
--   liftWith (\run -&gt; run t) &gt;&gt;= restoreT . return = t
--   </pre>
--   
--   <tt>restoreT</tt> is usually implemented through the constructor of
--   the monad transformer:
--   
--   <pre>
--   <a>ReaderT</a>  :: (r -&gt; m a) -&gt; <a>ReaderT</a> r m a
--   restoreT ::       m a  -&gt; <a>ReaderT</a> r m a
--   restoreT action = <a>ReaderT</a> { runReaderT = <a>const</a> action }
--   
--   <a>StateT</a>   :: (s -&gt; m (a, s)) -&gt; <a>StateT</a> s m a
--   restoreT ::       m (a, s)  -&gt; <a>StateT</a> s m a
--   restoreT action = <a>StateT</a> { runStateT = <a>const</a> action }
--   
--   <a>MaybeT</a>   :: m (<a>Maybe</a> a) -&gt; <a>MaybeT</a> m a
--   restoreT :: m (<a>Maybe</a> a) -&gt; <a>MaybeT</a> m a
--   restoreT action = <a>MaybeT</a> action
--   </pre>
--   
--   Example type signatures:
--   
--   <pre>
--   restoreT :: <a>Monad</a> m             =&gt; m a            -&gt; <a>IdentityT</a> m a
--   restoreT :: <a>Monad</a> m             =&gt; m (<a>Maybe</a> a)    -&gt; <a>MaybeT</a> m a
--   restoreT :: (<a>Monad</a> m, <a>Error</a> e)  =&gt; m (<a>Either</a> e a) -&gt; <a>ErrorT</a> e m a
--   restoreT :: <a>Monad</a> m             =&gt; m (<a>Either</a> e a) -&gt; <a>ExceptT</a> e m a
--   restoreT :: <a>Monad</a> m             =&gt; m [a]          -&gt; <a>ListT</a> m a
--   restoreT :: <a>Monad</a> m             =&gt; m a            -&gt; <a>ReaderT</a> r m a
--   restoreT :: <a>Monad</a> m             =&gt; m (a, s)       -&gt; <a>StateT</a> s m a
--   restoreT :: (<a>Monad</a> m, <a>Monoid</a> w) =&gt; m (a, w)       -&gt; <a>WriterT</a> w m a
--   restoreT :: (<a>Monad</a> m, <a>Monoid</a> w) =&gt; m (a, s, w)    -&gt; <a>RWST</a> r w s m a
--   </pre>
restoreT :: (MonadTransControl t, Monad m) => m (StT t a) -> t m a

-- | <h2>Writing instances</h2>
--   
--   The usual way to write a <tt><a>MonadBaseControl</a></tt> instance for
--   a transformer stack over a base monad <tt>B</tt> is to write an
--   instance <tt>MonadBaseControl B B</tt> for the base monad, and
--   <tt>MonadTransControl T</tt> instances for every transformer
--   <tt>T</tt>. Instances for <tt><a>MonadBaseControl</a></tt> are then
--   simply implemented using <tt><a>ComposeSt</a></tt>,
--   <tt><a>defaultLiftBaseWith</a></tt>, <tt><a>defaultRestoreM</a></tt>.
class MonadBase b m => MonadBaseControl (b :: * -> *) (m :: * -> *) | m -> b where type StM (m :: * -> *) a :: * where {
    type family StM (m :: * -> *) a :: *;
}

-- | <tt>liftBaseWith</tt> is similar to <tt>liftIO</tt> and
--   <tt>liftBase</tt> in that it lifts a base computation to the
--   constructed monad.
--   
--   Instances should satisfy similar laws as the <tt>MonadIO</tt> and
--   <a>MonadBase</a> laws:
--   
--   <pre>
--   liftBaseWith . const . return = return
--   </pre>
--   
--   <pre>
--   liftBaseWith (const (m &gt;&gt;= f)) = liftBaseWith (const m) &gt;&gt;= liftBaseWith . const . f
--   </pre>
--   
--   The difference with <tt>liftBase</tt> is that before lifting the base
--   computation <tt>liftBaseWith</tt> captures the state of <tt>m</tt>. It
--   then provides the base computation with a <a>RunInBase</a> function
--   that allows running <tt>m</tt> computations in the base monad on the
--   captured state:
--   
--   <pre>
--   withFileLifted :: MonadBaseControl IO m =&gt; FilePath -&gt; IOMode -&gt; (Handle -&gt; m a) -&gt; m a
--   withFileLifted file mode action = liftBaseWith (\runInBase -&gt; withFile file mode (runInBase . action)) &gt;&gt;= restoreM
--                                -- = control $ \runInBase -&gt; withFile file mode (runInBase . action)
--                                -- = liftBaseOp (withFile file mode) action
--   </pre>
--   
--   <tt><a>liftBaseWith</a></tt> is usually not implemented directly, but
--   using <tt><a>defaultLiftBaseWith</a></tt>.
liftBaseWith :: MonadBaseControl b m => (RunInBase m b -> b a) -> m a

-- | Construct a <tt>m</tt> computation from the monadic state of
--   <tt>m</tt> that is returned from a <a>RunInBase</a> function.
--   
--   Instances should satisfy:
--   
--   <pre>
--   liftBaseWith (\runInBase -&gt; runInBase m) &gt;&gt;= restoreM = m
--   </pre>
--   
--   <tt><a>restoreM</a></tt> is usually not implemented directly, but
--   using <tt><a>defaultRestoreM</a></tt>.
restoreM :: MonadBaseControl b m => StM m a -> m a
instance Control.Monad.Trans.Control.StT t a ~ a => Control.Monad.Trans.Unlift.Identical t a
instance (Control.Monad.Trans.Control.MonadTransControl t, Data.Constraint.Forall.Forall (Control.Monad.Trans.Unlift.Identical t)) => Control.Monad.Trans.Unlift.MonadTransUnlift t
instance Control.Monad.Trans.Control.StM m a ~ a => Control.Monad.Trans.Unlift.IdenticalBase m a
instance (Control.Monad.Trans.Control.MonadBaseControl b m, Data.Constraint.Forall.Forall (Control.Monad.Trans.Unlift.IdenticalBase m)) => Control.Monad.Trans.Unlift.MonadBaseUnlift b m
