-- 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)
class MonadTrans (t :: Type -> Type -> Type -> Type)
lift :: (MonadTrans t, Monad m) => m a -> t m a
class (Applicative b, Applicative m, Monad b, Monad m) => MonadBase (b :: Type -> Type) (m :: Type -> Type) | 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 :: Type -> Type -> Type -> Type) where {
    
    -- | Monadic state of <tt>t</tt>.
    --   
    --   The monadic state of a monad transformer is the result type of its
    --   <tt>run</tt> function, e.g.:
    --   
    --   <pre>
    --   <a>runReaderT</a> :: <a>ReaderT</a> r m a -&gt; r -&gt; m a
    --   <a>StT</a> (<a>ReaderT</a> r) a ~ a
    --   
    --   <a>runStateT</a> :: <a>StateT</a> s m a -&gt; s -&gt; m (a, s)
    --   <a>StT</a> (<a>StateT</a> s) a ~ (a, s)
    --   
    --   <a>runMaybeT</a> :: <a>MaybeT</a> m a -&gt; m (<a>Maybe</a> a)
    --   <a>StT</a> <a>MaybeT</a> a ~ <a>Maybe</a> a
    --   </pre>
    --   
    --   Provided type instances:
    --   
    --   <pre>
    --   StT <a>IdentityT</a>    a ~ a
    --   StT <a>MaybeT</a>       a ~ <a>Maybe</a> a
    --   StT (<a>ErrorT</a> e)   a ~ <a>Error</a> e =&gt; <a>Either</a> e a
    --   StT (<a>ExceptT</a> e)  a ~ <a>Either</a> e a
    --   StT <a>ListT</a>        a ~ [a]
    --   StT (<a>ReaderT</a> r)  a ~ a
    --   StT (<a>StateT</a> s)   a ~ (a, s)
    --   StT (<a>WriterT</a> w)  a ~ <a>Monoid</a> w =&gt; (a, w)
    --   StT (<a>RWST</a> r w s) a ~ <a>Monoid</a> w =&gt; (a, s, w)
    --   </pre>
    type family StT (t :: Type -> Type -> Type -> Type) 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 :: Type -> Type) (m :: Type -> Type) | m -> b where {
    
    -- | Monadic state that <tt>m</tt> adds to the base monad <tt>b</tt>.
    --   
    --   For all base (non-transformed) monads, <tt>StM m a ~ a</tt>:
    --   
    --   <pre>
    --   StM <a>IO</a>         a ~ a
    --   StM <a>Maybe</a>      a ~ a
    --   StM (<a>Either</a> e) a ~ a
    --   StM []         a ~ a
    --   StM ((-&gt;) r)   a ~ a
    --   StM <a>Identity</a>   a ~ a
    --   StM <a>STM</a>        a ~ a
    --   StM (<a>ST</a> s)     a ~ a
    --   </pre>
    --   
    --   If <tt>m</tt> is a transformed monad, <tt>m ~ t b</tt>,
    --   <tt><a>StM</a></tt> is the monadic state of the transformer <tt>t</tt>
    --   (given by its <a>StT</a> from <a>MonadTransControl</a>). For a
    --   transformer stack, <tt><a>StM</a></tt> is defined recursively:
    --   
    --   <pre>
    --   StM (<a>IdentityT</a>  m) a ~ <a>ComposeSt</a> <a>IdentityT</a> m a ~ StM m a
    --   StM (<a>MaybeT</a>     m) a ~ <a>ComposeSt</a> <a>MaybeT</a>    m a ~ StM m (<a>Maybe</a> a)
    --   StM (<a>ErrorT</a> e   m) a ~ <a>ComposeSt</a> <a>ErrorT</a>    m a ~ <a>Error</a> e =&gt; StM m (<a>Either</a> e a)
    --   StM (<a>ExceptT</a> e  m) a ~ <a>ComposeSt</a> <a>ExceptT</a>   m a ~ StM m (<a>Either</a> e a)
    --   StM (<a>ListT</a>      m) a ~ <a>ComposeSt</a> <a>ListT</a>     m a ~ StM m [a]
    --   StM (<a>ReaderT</a> r  m) a ~ <a>ComposeSt</a> <a>ReaderT</a>   m a ~ StM m a
    --   StM (<a>StateT</a> s   m) a ~ <a>ComposeSt</a> <a>StateT</a>    m a ~ StM m (a, s)
    --   StM (<a>WriterT</a> w  m) a ~ <a>ComposeSt</a> <a>WriterT</a>   m a ~ <a>Monoid</a> w =&gt; StM m (a, w)
    --   StM (<a>RWST</a> r w s m) a ~ <a>ComposeSt</a> <a>RWST</a>      m a ~ <a>Monoid</a> w =&gt; StM m (a, s, w)
    --   </pre>
    type family StM (m :: Type -> Type) 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.MonadBaseControl b m, Data.Constraint.Forall.Forall (Control.Monad.Trans.Unlift.IdenticalBase m)) => Control.Monad.Trans.Unlift.MonadBaseUnlift b m
instance (Control.Monad.Trans.Control.StM m a GHC.Types.~ a) => Control.Monad.Trans.Unlift.IdenticalBase m 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.StT t a GHC.Types.~ a) => Control.Monad.Trans.Unlift.Identical t a
