-- 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 :: 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 :: b α -> m α
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.
liftWith :: 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>
restoreT :: Monad m => m (StT t a) -> t m a
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.
liftBaseWith :: (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>
restoreM :: 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
