    {-# LANGUAGE CPP #-}

    {-| Many actions in base monad transformers cannot be automatically
        'Control.Monad.Trans.Class.lift'ed.  These functions lift these remaining
        actions so that they work in the 'Proxy' monad transformer.

        See the mini-tutorial at the bottom of this module for example code and
        typical use cases where this module will come in handy.
    -}

    module Pipes.Lift (
        -- * Utilities
          distribute

        -- * ExceptT
        , exceptP
        , runExceptP
        , catchError
        , liftCatchError

        -- * MaybeT
        , maybeP
        , runMaybeP

        -- * ReaderT
        , readerP
        , runReaderP

        -- * StateT
        , stateP
        , runStateP
        , evalStateP
        , execStateP

        -- * WriterT
        -- $writert
        , writerP
        , runWriterP
        , execWriterP

        -- * RWST
        , rwsP
        , runRWSP
        , evalRWSP
        , execRWSP

        -- * Tutorial
        -- $tutorial
        ) where

    import Control.Monad.Trans.Class (lift, MonadTrans(..))
    import qualified Control.Monad.Trans.Except as E
    import qualified Control.Monad.Trans.Maybe as M
    import qualified Control.Monad.Trans.Reader as R
    import qualified Control.Monad.Trans.State.Strict as S
    import qualified Control.Monad.Trans.Writer.Strict as W
    import qualified Control.Monad.Trans.RWS.Strict as RWS
    import Pipes.Internal (Proxy(..), unsafeHoist)
    import Control.Monad.Morph (hoist, MFunctor(..))
    import Pipes.Core (runEffect, request, respond, (//>), (>\\))

    #if MIN_VERSION_base(4,8,0)
    #else
    import Data.Monoid
    #endif

    -- | Distribute 'Proxy' over a monad transformer
    distribute
        ::  ( Monad m
            , MonadTrans t
            , MFunctor t
            , Monad (t m)
            , Monad (t (Proxy a' a b' b m))
            )
        => Proxy a' a b' b (t m) r
        -- ^
        -> t (Proxy a' a b' b m) r
        -- ^
    distribute :: forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute Proxy a' a b' b (t m) r
    p =  Effect (t (Proxy a' a b' b m)) r -> t (Proxy a' a b' b m) r
    forall (m :: * -> *) r. Monad m => Effect m r -> m r
    runEffect (Effect (t (Proxy a' a b' b m)) r -> t (Proxy a' a b' b m) r)
    -> Effect (t (Proxy a' a b' b m)) r -> t (Proxy a' a b' b m) r
    forall a b. (a -> b) -> a -> b
    $ a' -> Proxy X () b' b (t (Proxy a' a b' b m)) a
    request' (a' -> Proxy X () b' b (t (Proxy a' a b' b m)) a)
    -> Proxy a' a b' b (t (Proxy a' a b' b m)) r
    -> Proxy X () b' b (t (Proxy a' a b' b m)) r
    forall (m :: * -> *) b' a' a y' y b c.
    Functor m =>
    (b' -> Proxy a' a y' y m b)
    -> Proxy b' b y' y m c -> Proxy a' a y' y m c
    >\\ (forall x. t m x -> t (Proxy a' a b' b m) x)
    -> Proxy a' a b' b (t m) r
    -> Proxy a' a b' b (t (Proxy a' a b' b m)) r
    forall (m :: * -> *) (n :: * -> *) a' a b' b r.
    Functor m =>
    (forall x. m x -> n x)
    -> Proxy a' a b' b m r -> Proxy a' a b' b n r
    unsafeHoist ((forall a. m a -> Proxy a' a b' b m a)
    -> t m x -> t (Proxy a' a b' b m) x
    forall {k} (t :: (* -> *) -> k -> *) (m :: * -> *) (n :: * -> *)
           (b :: k).
    (MFunctor t, Monad m) =>
    (forall a. m a -> n a) -> t m b -> t n b
    forall (m :: * -> *) (n :: * -> *) b.
    Monad m =>
    (forall a. m a -> n a) -> t m b -> t n b
    hoist m a -> Proxy a' a b' b m a
    forall a. m a -> Proxy a' a b' b m a
    forall (m :: * -> *) a. Monad m => m a -> Proxy a' a b' b m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift) Proxy a' a b' b (t m) r
    p Proxy X () b' b (t (Proxy a' a b' b m)) r
    -> (b -> Proxy X () () X (t (Proxy a' a b' b m)) b')
    -> Effect (t (Proxy a' a b' b m)) r
    forall (m :: * -> *) x' x b' b a' c' c.
    Functor m =>
    Proxy x' x b' b m a'
    -> (b -> Proxy x' x c' c m b') -> Proxy x' x c' c m a'
    //> b -> Proxy X () () X (t (Proxy a' a b' b m)) b'
    respond'
      where
        request' :: a' -> Proxy X () b' b (t (Proxy a' a b' b m)) a
    request' = t (Proxy a' a b' b m) a
    -> Proxy X () b' b (t (Proxy a' a b' b m)) a
    forall (m :: * -> *) a. Monad m => m a -> Proxy X () b' b m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (t (Proxy a' a b' b m) a
     -> Proxy X () b' b (t (Proxy a' a b' b m)) a)
    -> (a' -> t (Proxy a' a b' b m) a)
    -> a'
    -> Proxy X () b' b (t (Proxy a' a b' b m)) a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Proxy a' a b' b m a -> t (Proxy a' a b' b m) a
    forall (m :: * -> *) a. Monad m => m a -> t m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (Proxy a' a b' b m a -> t (Proxy a' a b' b m) a)
    -> (a' -> Proxy a' a b' b m a) -> a' -> t (Proxy a' a b' b m) a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a' -> Proxy a' a b' b m a
    forall (m :: * -> *) a' a y' y.
    Functor m =>
    a' -> Proxy a' a y' y m a
    request
        respond' :: b -> Proxy X () () X (t (Proxy a' a b' b m)) b'
    respond' = t (Proxy a' a b' b m) b'
    -> Proxy X () () X (t (Proxy a' a b' b m)) b'
    forall (m :: * -> *) a. Monad m => m a -> Proxy X () () X m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (t (Proxy a' a b' b m) b'
     -> Proxy X () () X (t (Proxy a' a b' b m)) b')
    -> (b -> t (Proxy a' a b' b m) b')
    -> b
    -> Proxy X () () X (t (Proxy a' a b' b m)) b'
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Proxy a' a b' b m b' -> t (Proxy a' a b' b m) b'
    forall (m :: * -> *) a. Monad m => m a -> t m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (Proxy a' a b' b m b' -> t (Proxy a' a b' b m) b')
    -> (b -> Proxy a' a b' b m b') -> b -> t (Proxy a' a b' b m) b'
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . b -> Proxy a' a b' b m b'
    forall (m :: * -> *) a x' x a'.
    Functor m =>
    a -> Proxy x' x a' a m a'
    respond
    {-# INLINABLE distribute #-}

    -- | Wrap the base monad in 'E.ExceptT'
    exceptP
        :: Monad m
        => Proxy a' a b' b m (Either e r)
        -> Proxy a' a b' b (E.ExceptT e m) r
    exceptP :: forall (m :: * -> *) a' a b' b e r.
    Monad m =>
    Proxy a' a b' b m (Either e r) -> Proxy a' a b' b (ExceptT e m) r
    exceptP Proxy a' a b' b m (Either e r)
    p = do
        x <- (forall x. m x -> ExceptT e m x)
    -> Proxy a' a b' b m (Either e r)
    -> Proxy a' a b' b (ExceptT e m) (Either e r)
    forall (m :: * -> *) (n :: * -> *) a' a b' b r.
    Functor m =>
    (forall x. m x -> n x)
    -> Proxy a' a b' b m r -> Proxy a' a b' b n r
    unsafeHoist m x -> ExceptT e m x
    forall x. m x -> ExceptT e m x
    forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift Proxy a' a b' b m (Either e r)
    p
        lift $ E.ExceptT (return x)
    {-# INLINABLE exceptP #-}

    -- | Run 'E.ExceptT' in the base monad
    runExceptP
        :: Monad m
        => Proxy a' a b' b (E.ExceptT e m) r
        -> Proxy a' a b' b m (Either e r)
    runExceptP :: forall (m :: * -> *) a' a b' b e r.
    Monad m =>
    Proxy a' a b' b (ExceptT e m) r -> Proxy a' a b' b m (Either e r)
    runExceptP    = ExceptT e (Proxy a' a b' b m) r -> Proxy a' a b' b m (Either e r)
    forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    E.runExceptT (ExceptT e (Proxy a' a b' b m) r -> Proxy a' a b' b m (Either e r))
    -> (Proxy a' a b' b (ExceptT e m) r
        -> ExceptT e (Proxy a' a b' b m) r)
    -> Proxy a' a b' b (ExceptT e m) r
    -> Proxy a' a b' b m (Either e r)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Proxy a' a b' b (ExceptT e m) r -> ExceptT e (Proxy a' a b' b m) r
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute
    {-# INLINABLE runExceptP #-}

    -- | Catch an error in the base monad
    catchError
        :: Monad m
        => Proxy a' a b' b (E.ExceptT e m) r
        -- ^
        -> (e -> Proxy a' a b' b (E.ExceptT e m) r)
        -- ^
        -> Proxy a' a b' b (E.ExceptT e m) r
    catchError :: forall (m :: * -> *) a' a b' b e r.
    Monad m =>
    Proxy a' a b' b (ExceptT e m) r
    -> (e -> Proxy a' a b' b (ExceptT e m) r)
    -> Proxy a' a b' b (ExceptT e m) r
    catchError Proxy a' a b' b (ExceptT e m) r
    e e -> Proxy a' a b' b (ExceptT e m) r
    h = Proxy a' a b' b m (Either e r) -> Proxy a' a b' b (ExceptT e m) r
    forall (m :: * -> *) a' a b' b e r.
    Monad m =>
    Proxy a' a b' b m (Either e r) -> Proxy a' a b' b (ExceptT e m) r
    exceptP (Proxy a' a b' b m (Either e r) -> Proxy a' a b' b (ExceptT e m) r)
    -> (ExceptT e (Proxy a' a b' b m) r
        -> Proxy a' a b' b m (Either e r))
    -> ExceptT e (Proxy a' a b' b m) r
    -> Proxy a' a b' b (ExceptT e m) r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ExceptT e (Proxy a' a b' b m) r -> Proxy a' a b' b m (Either e r)
    forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    E.runExceptT (ExceptT e (Proxy a' a b' b m) r
     -> Proxy a' a b' b (ExceptT e m) r)
    -> ExceptT e (Proxy a' a b' b m) r
    -> Proxy a' a b' b (ExceptT e m) r
    forall a b. (a -> b) -> a -> b
    $
        ExceptT e (Proxy a' a b' b m) r
    -> (e -> ExceptT e (Proxy a' a b' b m) r)
    -> ExceptT e (Proxy a' a b' b m) r
    forall (m :: * -> *) e a e'.
    Monad m =>
    ExceptT e m a -> (e -> ExceptT e' m a) -> ExceptT e' m a
    E.catchE (Proxy a' a b' b (ExceptT e m) r -> ExceptT e (Proxy a' a b' b m) r
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute Proxy a' a b' b (ExceptT e m) r
    e) (Proxy a' a b' b (ExceptT e m) r -> ExceptT e (Proxy a' a b' b m) r
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute (Proxy a' a b' b (ExceptT e m) r
     -> ExceptT e (Proxy a' a b' b m) r)
    -> (e -> Proxy a' a b' b (ExceptT e m) r)
    -> e
    -> ExceptT e (Proxy a' a b' b m) r
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . e -> Proxy a' a b' b (ExceptT e m) r
    h)
    {-# INLINABLE catchError #-}

    -- | Catch an error using a catch function for the base monad
    liftCatchError
        :: Monad m
        => (   m (Proxy a' a b' b m r)
            -> (e -> m (Proxy a' a b' b m r))
            -> m (Proxy a' a b' b m r) )
        -- ^
        ->    (Proxy a' a b' b m r
            -> (e -> Proxy a' a b' b m r)
            -> Proxy a' a b' b m r)
        -- ^
    liftCatchError :: forall (m :: * -> *) a' a b' b r e.
    Monad m =>
    (m (Proxy a' a b' b m r)
     -> (e -> m (Proxy a' a b' b m r)) -> m (Proxy a' a b' b m r))
    -> Proxy a' a b' b m r
    -> (e -> Proxy a' a b' b m r)
    -> Proxy a' a b' b m r
    liftCatchError m (Proxy a' a b' b m r)
    -> (e -> m (Proxy a' a b' b m r)) -> m (Proxy a' a b' b m r)
    c Proxy a' a b' b m r
    p0 e -> Proxy a' a b' b m r
    f = Proxy a' a b' b m r -> Proxy a' a b' b m r
    go Proxy a' a b' b m r
    p0
      where
        go :: Proxy a' a b' b m r -> Proxy a' a b' b m r
    go Proxy a' a b' b m r
    p = case Proxy a' a b' b m r
    p of
            Request a'
    a' a -> Proxy a' a b' b m r
    fa  -> a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
    forall a' a b' b (m :: * -> *) r.
    a' -> (a -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
    Request a'
    a' (\a
    a  -> Proxy a' a b' b m r -> Proxy a' a b' b m r
    go (a -> Proxy a' a b' b m r
    fa  a
    a ))
            Respond b
    b  b' -> Proxy a' a b' b m r
    fb' -> b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
    forall a' a b' b (m :: * -> *) r.
    b -> (b' -> Proxy a' a b' b m r) -> Proxy a' a b' b m r
    Respond b
    b  (\b'
    b' -> Proxy a' a b' b m r -> Proxy a' a b' b m r
    go (b' -> Proxy a' a b' b m r
    fb' b'
    b'))
            Pure    r
    r      -> r -> Proxy a' a b' b m r
    forall a' a b' b (m :: * -> *) r. r -> Proxy a' a b' b m r
    Pure r
    r
            M          m (Proxy a' a b' b m r)
    m   -> m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
    forall a' a b' b (m :: * -> *) r.
    m (Proxy a' a b' b m r) -> Proxy a' a b' b m r
    M ((do
                p' <- m (Proxy a' a b' b m r)
    m
                return (go p') ) m (Proxy a' a b' b m r)
    -> (e -> m (Proxy a' a b' b m r)) -> m (Proxy a' a b' b m r)
    `c` (\e
    e -> Proxy a' a b' b m r -> m (Proxy a' a b' b m r)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (e -> Proxy a' a b' b m r
    f e
    e)) )
    {-# INLINABLE liftCatchError #-}

    -- | Wrap the base monad in 'M.MaybeT'
    maybeP
        :: Monad m
        => Proxy a' a b' b m (Maybe r) -> Proxy a' a b' b (M.MaybeT m) r
    maybeP :: forall (m :: * -> *) a' a b' b r.
    Monad m =>
    Proxy a' a b' b m (Maybe r) -> Proxy a' a b' b (MaybeT m) r
    maybeP Proxy a' a b' b m (Maybe r)
    p = do
        x <- (forall x. m x -> MaybeT m x)
    -> Proxy a' a b' b m (Maybe r)
    -> Proxy a' a b' b (MaybeT m) (Maybe r)
    forall (m :: * -> *) (n :: * -> *) a' a b' b r.
    Functor m =>
    (forall x. m x -> n x)
    -> Proxy a' a b' b m r -> Proxy a' a b' b n r
    unsafeHoist m x -> MaybeT m x
    forall x. m x -> MaybeT m x
    forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift Proxy a' a b' b m (Maybe r)
    p
        lift $ M.MaybeT (return x)
    {-# INLINABLE maybeP #-}

    -- | Run 'M.MaybeT' in the base monad
    runMaybeP
        :: Monad m
        => Proxy a' a b' b (M.MaybeT m) r
        -> Proxy a' a b' b m (Maybe r)
    runMaybeP :: forall (m :: * -> *) a' a b' b r.
    Monad m =>
    Proxy a' a b' b (MaybeT m) r -> Proxy a' a b' b m (Maybe r)
    runMaybeP Proxy a' a b' b (MaybeT m) r
    p = MaybeT (Proxy a' a b' b m) r -> Proxy a' a b' b m (Maybe r)
    forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
    M.runMaybeT (MaybeT (Proxy a' a b' b m) r -> Proxy a' a b' b m (Maybe r))
    -> MaybeT (Proxy a' a b' b m) r -> Proxy a' a b' b m (Maybe r)
    forall a b. (a -> b) -> a -> b
    $ Proxy a' a b' b (MaybeT m) r -> MaybeT (Proxy a' a b' b m) r
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute Proxy a' a b' b (MaybeT m) r
    p
    {-# INLINABLE runMaybeP #-}

    -- | Wrap the base monad in 'R.ReaderT'
    readerP
        :: Monad m
        => (i -> Proxy a' a b' b m r) -> Proxy a' a b' b (R.ReaderT i m) r
    readerP :: forall (m :: * -> *) i a' a b' b r.
    Monad m =>
    (i -> Proxy a' a b' b m r) -> Proxy a' a b' b (ReaderT i m) r
    readerP i -> Proxy a' a b' b m r
    k = do
        i <- ReaderT i m i -> Proxy a' a b' b (ReaderT i m) i
    forall (m :: * -> *) a. Monad m => m a -> Proxy a' a b' b m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift ReaderT i m i
    forall (m :: * -> *) r. Monad m => ReaderT r m r
    R.ask
        unsafeHoist lift (k i)
    {-# INLINABLE readerP #-}

    -- | Run 'R.ReaderT' in the base monad
    runReaderP
        :: Monad m
        => i
        -> Proxy a' a b' b (R.ReaderT i m) r
        -> Proxy a' a b' b m r
    runReaderP :: forall (m :: * -> *) i a' a b' b r.
    Monad m =>
    i -> Proxy a' a b' b (ReaderT i m) r -> Proxy a' a b' b m r
    runReaderP i
    r Proxy a' a b' b (ReaderT i m) r
    p = (ReaderT i (Proxy a' a b' b m) r -> i -> Proxy a' a b' b m r
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    `R.runReaderT` i
    r) (ReaderT i (Proxy a' a b' b m) r -> Proxy a' a b' b m r)
    -> ReaderT i (Proxy a' a b' b m) r -> Proxy a' a b' b m r
    forall a b. (a -> b) -> a -> b
    $ Proxy a' a b' b (ReaderT i m) r -> ReaderT i (Proxy a' a b' b m) r
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute Proxy a' a b' b (ReaderT i m) r
    p
    {-# INLINABLE runReaderP #-}

    -- | Wrap the base monad in 'S.StateT'
    stateP
        :: Monad m
        => (s -> Proxy a' a b' b m (r, s)) -> Proxy a' a b' b (S.StateT s m) r
    stateP :: forall (m :: * -> *) s a' a b' b r.
    Monad m =>
    (s -> Proxy a' a b' b m (r, s)) -> Proxy a' a b' b (StateT s m) r
    stateP s -> Proxy a' a b' b m (r, s)
    k = do
        s <- StateT s m s -> Proxy a' a b' b (StateT s m) s
    forall (m :: * -> *) a. Monad m => m a -> Proxy a' a b' b m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift StateT s m s
    forall (m :: * -> *) s. Monad m => StateT s m s
    S.get
        (r, s') <- unsafeHoist lift (k s)
        lift (S.put s')
        return r
    {-# INLINABLE stateP #-}

    -- | Run 'S.StateT' in the base monad
    runStateP
        :: Monad m
        => s
        -> Proxy a' a b' b (S.StateT s m) r
        -> Proxy a' a b' b m (r, s)
    runStateP :: forall (m :: * -> *) s a' a b' b r.
    Monad m =>
    s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m (r, s)
    runStateP s
    s Proxy a' a b' b (StateT s m) r
    p = (StateT s (Proxy a' a b' b m) r -> s -> Proxy a' a b' b m (r, s)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    `S.runStateT` s
    s) (StateT s (Proxy a' a b' b m) r -> Proxy a' a b' b m (r, s))
    -> StateT s (Proxy a' a b' b m) r -> Proxy a' a b' b m (r, s)
    forall a b. (a -> b) -> a -> b
    $ Proxy a' a b' b (StateT s m) r -> StateT s (Proxy a' a b' b m) r
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute Proxy a' a b' b (StateT s m) r
    p
    {-# INLINABLE runStateP #-}

    -- | Evaluate 'S.StateT' in the base monad
    evalStateP
        :: Monad m
        => s
        -> Proxy a' a b' b (S.StateT s m) r
        -> Proxy a' a b' b m r
    evalStateP :: forall (m :: * -> *) s a' a b' b r.
    Monad m =>
    s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m r
    evalStateP s
    s Proxy a' a b' b (StateT s m) r
    p = ((r, s) -> r) -> Proxy a' a b' b m (r, s) -> Proxy a' a b' b m r
    forall a b. (a -> b) -> Proxy a' a b' b m a -> Proxy a' a b' b m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (r, s) -> r
    forall a b. (a, b) -> a
    fst (Proxy a' a b' b m (r, s) -> Proxy a' a b' b m r)
    -> Proxy a' a b' b m (r, s) -> Proxy a' a b' b m r
    forall a b. (a -> b) -> a -> b
    $ s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m (r, s)
    forall (m :: * -> *) s a' a b' b r.
    Monad m =>
    s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m (r, s)
    runStateP s
    s Proxy a' a b' b (StateT s m) r
    p
    {-# INLINABLE evalStateP #-}

    -- | Execute 'S.StateT' in the base monad
    execStateP
        :: Monad m
        => s
        -> Proxy a' a b' b (S.StateT s m) r
        -> Proxy a' a b' b m s
    execStateP :: forall (m :: * -> *) s a' a b' b r.
    Monad m =>
    s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m s
    execStateP s
    s Proxy a' a b' b (StateT s m) r
    p = ((r, s) -> s) -> Proxy a' a b' b m (r, s) -> Proxy a' a b' b m s
    forall a b. (a -> b) -> Proxy a' a b' b m a -> Proxy a' a b' b m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (r, s) -> s
    forall a b. (a, b) -> b
    snd (Proxy a' a b' b m (r, s) -> Proxy a' a b' b m s)
    -> Proxy a' a b' b m (r, s) -> Proxy a' a b' b m s
    forall a b. (a -> b) -> a -> b
    $ s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m (r, s)
    forall (m :: * -> *) s a' a b' b r.
    Monad m =>
    s -> Proxy a' a b' b (StateT s m) r -> Proxy a' a b' b m (r, s)
    runStateP s
    s Proxy a' a b' b (StateT s m) r
    p
    {-# INLINABLE execStateP #-}

    {- $writert
        Note that 'runWriterP' and 'execWriterP' will keep the accumulator in
        weak-head-normal form so that folds run in constant space when possible.

        This means that until @transformers@ adds a truly strict 'W.WriterT', you
        should consider unwrapping 'W.WriterT' first using 'runWriterP' or
        'execWriterP' before running your 'Proxy'.  You will get better performance
        this way and eliminate space leaks if your accumulator doesn't have any lazy
        fields.
    -}

    -- | Wrap the base monad in 'W.WriterT'
    writerP
        :: (Monad m, Monoid w)
        => Proxy a' a b' b m (r, w) -> Proxy a' a b' b (W.WriterT w m) r
    writerP :: forall (m :: * -> *) w a' a b' b r.
    (Monad m, Monoid w) =>
    Proxy a' a b' b m (r, w) -> Proxy a' a b' b (WriterT w m) r
    writerP Proxy a' a b' b m (r, w)
    p = do
        (r, w) <- (forall x. m x -> WriterT w m x)
    -> Proxy a' a b' b m (r, w) -> Proxy a' a b' b (WriterT w m) (r, w)
    forall (m :: * -> *) (n :: * -> *) a' a b' b r.
    Functor m =>
    (forall x. m x -> n x)
    -> Proxy a' a b' b m r -> Proxy a' a b' b n r
    unsafeHoist m x -> WriterT w m x
    forall x. m x -> WriterT w m x
    forall (m :: * -> *) a. Monad m => m a -> WriterT w m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift Proxy a' a b' b m (r, w)
    p
        lift $ W.tell w
        return r
    {-# INLINABLE writerP #-}

    -- | Run 'W.WriterT' in the base monad
    runWriterP
        :: (Monad m, Monoid w)
        => Proxy a' a b' b (W.WriterT w m) r
        -> Proxy a' a b' b m (r, w)
    runWriterP :: forall (m :: * -> *) w a' a b' b r.
    (Monad m, Monoid w) =>
    Proxy a' a b' b (WriterT w m) r -> Proxy a' a b' b m (r, w)
    runWriterP Proxy a' a b' b (WriterT w m) r
    p = WriterT w (Proxy a' a b' b m) r -> Proxy a' a b' b m (r, w)
    forall w (m :: * -> *) a. WriterT w m a -> m (a, w)
    W.runWriterT (WriterT w (Proxy a' a b' b m) r -> Proxy a' a b' b m (r, w))
    -> WriterT w (Proxy a' a b' b m) r -> Proxy a' a b' b m (r, w)
    forall a b. (a -> b) -> a -> b
    $ Proxy a' a b' b (WriterT w m) r -> WriterT w (Proxy a' a b' b m) r
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute Proxy a' a b' b (WriterT w m) r
    p
    {-# INLINABLE runWriterP #-}

    -- | Execute 'W.WriterT' in the base monad
    execWriterP
        :: (Monad m, Monoid w)
        => Proxy a' a b' b (W.WriterT w m) r
        -> Proxy a' a b' b m w
    execWriterP :: forall (m :: * -> *) w a' a b' b r.
    (Monad m, Monoid w) =>
    Proxy a' a b' b (WriterT w m) r -> Proxy a' a b' b m w
    execWriterP Proxy a' a b' b (WriterT w m) r
    p = ((r, w) -> w) -> Proxy a' a b' b m (r, w) -> Proxy a' a b' b m w
    forall a b. (a -> b) -> Proxy a' a b' b m a -> Proxy a' a b' b m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (r, w) -> w
    forall a b. (a, b) -> b
    snd (Proxy a' a b' b m (r, w) -> Proxy a' a b' b m w)
    -> Proxy a' a b' b m (r, w) -> Proxy a' a b' b m w
    forall a b. (a -> b) -> a -> b
    $ Proxy a' a b' b (WriterT w m) r -> Proxy a' a b' b m (r, w)
    forall (m :: * -> *) w a' a b' b r.
    (Monad m, Monoid w) =>
    Proxy a' a b' b (WriterT w m) r -> Proxy a' a b' b m (r, w)
    runWriterP Proxy a' a b' b (WriterT w m) r
    p
    {-# INLINABLE execWriterP #-}

    -- | Wrap the base monad in 'RWS.RWST'
    rwsP
        :: (Monad m, Monoid w)
        => (i -> s -> Proxy a' a b' b m (r, s, w))
        -> Proxy a' a b' b (RWS.RWST i w s m) r
    rwsP :: forall (m :: * -> *) w i s a' a b' b r.
    (Monad m, Monoid w) =>
    (i -> s -> Proxy a' a b' b m (r, s, w))
    -> Proxy a' a b' b (RWST i w s m) r
    rwsP i -> s -> Proxy a' a b' b m (r, s, w)
    k = do
        i <- RWST i w s m i -> Proxy a' a b' b (RWST i w s m) i
    forall (m :: * -> *) a. Monad m => m a -> Proxy a' a b' b m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift RWST i w s m i
    forall w (m :: * -> *) r s. (Monoid w, Monad m) => RWST r w s m r
    RWS.ask
        s <- lift RWS.get
        (r, s', w) <- unsafeHoist lift (k i s)
        lift $ do
            RWS.put s'
            RWS.tell w
        return r
    {-# INLINABLE rwsP #-}

    -- | Run 'RWS.RWST' in the base monad
    runRWSP
        :: (Monad m, Monoid w)
        => r
        -> s
        -> Proxy a' a b' b (RWS.RWST r w s m) d
        -> Proxy a' a b' b m (d, s, w)
    runRWSP :: forall (m :: * -> *) w r s a' a b' b d.
    (Monad m, Monoid w) =>
    r
    -> s
    -> Proxy a' a b' b (RWST r w s m) d
    -> Proxy a' a b' b m (d, s, w)
    runRWSP  r
    i s
    s Proxy a' a b' b (RWST r w s m) d
    p = (\RWST r w s (Proxy a' a b' b m) d
    b -> RWST r w s (Proxy a' a b' b m) d
    -> r -> s -> Proxy a' a b' b m (d, s, w)
    forall r w s (m :: * -> *) a.
    RWST r w s m a -> r -> s -> m (a, s, w)
    RWS.runRWST RWST r w s (Proxy a' a b' b m) d
    b r
    i s
    s) (RWST r w s (Proxy a' a b' b m) d -> Proxy a' a b' b m (d, s, w))
    -> RWST r w s (Proxy a' a b' b m) d -> Proxy a' a b' b m (d, s, w)
    forall a b. (a -> b) -> a -> b
    $ Proxy a' a b' b (RWST r w s m) d
    -> RWST r w s (Proxy a' a b' b m) d
    forall (m :: * -> *) (t :: (* -> *) -> * -> *) a' a b' b r.
    (Monad m, MonadTrans t, MFunctor t, Monad (t m),
     Monad (t (Proxy a' a b' b m))) =>
    Proxy a' a b' b (t m) r -> t (Proxy a' a b' b m) r
    distribute Proxy a' a b' b (RWST r w s m) d
    p
    {-# INLINABLE runRWSP #-}

    -- | Evaluate 'RWS.RWST' in the base monad
    evalRWSP
        :: (Monad m, Monoid w)
        => r
        -> s
        -> Proxy a' a b' b (RWS.RWST r w s m) d
        -> Proxy a' a b' b m (d, w)
    evalRWSP :: forall (m :: * -> *) w r s a' a b' b d.
    (Monad m, Monoid w) =>
    r
    -> s
    -> Proxy a' a b' b (RWST r w s m) d
    -> Proxy a' a b' b m (d, w)
    evalRWSP r
    i s
    s Proxy a' a b' b (RWST r w s m) d
    p = ((d, s, w) -> (d, w))
    -> Proxy a' a b' b m (d, s, w) -> Proxy a' a b' b m (d, w)
    forall a b. (a -> b) -> Proxy a' a b' b m a -> Proxy a' a b' b m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (d, s, w) -> (d, w)
    forall {a} {b} {b}. (a, b, b) -> (a, b)
    f (Proxy a' a b' b m (d, s, w) -> Proxy a' a b' b m (d, w))
    -> Proxy a' a b' b m (d, s, w) -> Proxy a' a b' b m (d, w)
    forall a b. (a -> b) -> a -> b
    $ r
    -> s
    -> Proxy a' a b' b (RWST r w s m) d
    -> Proxy a' a b' b m (d, s, w)
    forall (m :: * -> *) w r s a' a b' b d.
    (Monad m, Monoid w) =>
    r
    -> s
    -> Proxy a' a b' b (RWST r w s m) d
    -> Proxy a' a b' b m (d, s, w)
    runRWSP r
    i s
    s Proxy a' a b' b (RWST r w s m) d
    p
      where
        f :: (a, b, b) -> (a, b)
    f (a, b, b)
    x = let (a
    r, b
    _, b
    w) = (a, b, b)
    x in (a
    r, b
    w)
    {-# INLINABLE evalRWSP #-}

    -- | Execute 'RWS.RWST' in the base monad
    execRWSP
        :: (Monad m, Monoid w)
        => r
        -> s
        -> Proxy a' a b' b (RWS.RWST r w s m) d
        -> Proxy a' a b' b m (s, w)
    execRWSP :: forall (m :: * -> *) w r s a' a b' b d.
    (Monad m, Monoid w) =>
    r
    -> s
    -> Proxy a' a b' b (RWST r w s m) d
    -> Proxy a' a b' b m (s, w)
    execRWSP r
    i s
    s Proxy a' a b' b (RWST r w s m) d
    p = ((d, s, w) -> (s, w))
    -> Proxy a' a b' b m (d, s, w) -> Proxy a' a b' b m (s, w)
    forall a b. (a -> b) -> Proxy a' a b' b m a -> Proxy a' a b' b m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (d, s, w) -> (s, w)
    forall {a} {a} {b}. (a, a, b) -> (a, b)
    f (Proxy a' a b' b m (d, s, w) -> Proxy a' a b' b m (s, w))
    -> Proxy a' a b' b m (d, s, w) -> Proxy a' a b' b m (s, w)
    forall a b. (a -> b) -> a -> b
    $ r
    -> s
    -> Proxy a' a b' b (RWST r w s m) d
    -> Proxy a' a b' b m (d, s, w)
    forall (m :: * -> *) w r s a' a b' b d.
    (Monad m, Monoid w) =>
    r
    -> s
    -> Proxy a' a b' b (RWST r w s m) d
    -> Proxy a' a b' b m (d, s, w)
    runRWSP r
    i s
    s Proxy a' a b' b (RWST r w s m) d
    p
      where
        f :: (a, a, b) -> (a, b)
    f (a, a, b)
    x = let (a
    _, a
    s', b
    w) = (a, a, b)
    x in (a
    s', b
    w)
    {-# INLINABLE execRWSP #-}

    {- $tutorial
        Probably the most useful functionality in this module is lifted error
        handling.  Suppose that you have a 'Pipes.Pipe' whose base monad can fail
        using 'E.ExceptT':

    > import Control.Monad.Trans.Error
    > import Pipes
    >
    > example :: Monad m => Pipe Int Int (ExceptT String m) r
    > example = for cat $ \n ->
    >     if n == 0
    >     then lift $ throwError "Zero is forbidden"
    >     else yield n

        Without the tools in this module you cannot recover from any potential error
        until after you compose and run the pipeline:

    >>> import qualified Pipes.Prelude as P
    >>> runExceptT $ runEffect $ P.readLn >-> example >-> P.print
    42<Enter>
    42
    1<Enter>
    1
    0<Enter>
    Zero is forbidden
    >>>

        This module provides `catchError`, which lets you catch and recover from
        errors inside the 'Pipe':

    >  import qualified Pipes.Lift as Lift
    >
    >  caught :: Pipe Int Int (ExceptT String IO) r
    >  caught = example `Lift.catchError` \str -> do
    >      liftIO (putStrLn str)
    >      caught

        This lets you resume streaming in the face of errors raised within the base
        monad:

    >>> runExceptT $ runEffect $ P.readLn >-> caught >-> P.print
    0<Enter>
    Zero is forbidden
    42<Enter>
    42
    0<Enter>
    Zero is forbidden
    1<Enter>
    1
    ...

        Another common use case is running a base monad before running the pipeline.
        For example, the following contrived 'Producer' uses 'S.StateT' gratuitously
        to increment numbers:

    > import Control.Monad (forever)
    > import Control.Monad.Trans.State.Strict
    > import Pipes
    >
    > numbers :: Monad m => Producer Int (StateT Int m) r
    > numbers = forever $ do
    >     n <- lift get
    >     yield n
    >     lift $ put $! n + 1

        You can run the 'StateT' monad by supplying an initial state, before you
        ever compose the 'Producer':

    > import Pipes.Lift
    >
    > naturals :: Monad m => Producer Int m r
    > naturals = evalStateP 0 numbers

        This deletes 'StateT' from the base monad entirely, give you a completely
        pure 'Pipes.Producer':

    >>> Pipes.Prelude.toList naturals
    [0,1,2,3,4,5,6...]

        Note that the convention for the 'S.StateT' run functions is backwards from
        @transformers@ for convenience: the initial state is the first argument.

        All of these functions internally use 'distribute', which can pull out most
        monad transformers from the base monad.  For example, 'evalStateP' is
        defined in terms of 'distribute':

    > evalStateP s p = evalStateT (distribute p) s

        Therefore you can use 'distribute' to run other monad transformers, too, as
        long as they implement the 'MFunctor' type class from the @mmorph@ library.
    -}