    {-# LANGUAGE CPP #-}
    #if __GLASGOW_HASKELL__ >= 702
    {-# LANGUAGE Safe #-}
    #endif
    #if __GLASGOW_HASKELL__ >= 710
    {-# LANGUAGE AutoDeriveTypeable #-}
    #endif
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Control.Monad.Trans.Except
    -- Copyright   :  (C) 2013 Ross Paterson
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  R.Paterson@city.ac.uk
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- This monad transformer extends a monad with the ability to throw exceptions.
    --
    -- A sequence of actions terminates normally, producing a value,
    -- only if none of the actions in the sequence throws an exception.
    -- If one throws an exception, the rest of the sequence is skipped and
    -- the composite action exits with that exception.
    --
    -- If the value of the exception is not required, the variant in
    -- "Control.Monad.Trans.Maybe" may be used instead.
    -----------------------------------------------------------------------------

    module Control.Monad.Trans.Except (
        -- * The Except monad
        Except,
        except,
        runExcept,
        mapExcept,
        withExcept,
        -- * The ExceptT monad transformer
        ExceptT(ExceptT),
        runExceptT,
        mapExceptT,
        withExceptT,
        -- * Exception operations
        throwE,
        catchE,
        -- * Lifting other operations
        liftCallCC,
        liftListen,
        liftPass,
      ) where

    import Control.Monad.IO.Class
    import Control.Monad.Signatures
    import Control.Monad.Trans.Class
    import Data.Functor.Classes
    #if MIN_VERSION_base(4,12,0)
    import Data.Functor.Contravariant
    #endif
    import Data.Functor.Identity

    import Control.Applicative
    import Control.Monad
    #if MIN_VERSION_base(4,9,0)
    import qualified Control.Monad.Fail as Fail
    #endif
    import Control.Monad.Fix
    #if MIN_VERSION_base(4,4,0)
    import Control.Monad.Zip (MonadZip(mzipWith))
    #endif
    import Data.Foldable (Foldable(foldMap))
    import Data.Monoid
    import Data.Traversable (Traversable(traverse))

    -- | The parameterizable exception monad.
    --
    -- Computations are either exceptions or normal values.
    --
    -- The 'return' function returns a normal value, while @>>=@ exits on
    -- the first exception.  For a variant that continues after an error
    -- and collects all the errors, see 'Control.Applicative.Lift.Errors'.
    type Except e = ExceptT e Identity

    -- | Constructor for computations in the exception monad.
    -- (The inverse of 'runExcept').
    except :: (Monad m) => Either e a -> ExceptT e m a
    except :: forall (m :: * -> *) e a. Monad m => Either e a -> ExceptT e m a
    except Either e a
    m = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT (forall (m :: * -> *) a. Monad m => a -> m a
    return Either e a
    m)
    {-# INLINE except #-}

    -- | Extractor for computations in the exception monad.
    -- (The inverse of 'except').
    runExcept :: Except e a -> Either e a
    runExcept :: forall e a. Except e a -> Either e a
    runExcept (ExceptT Identity (Either e a)
    m) = forall a. Identity a -> a
    runIdentity Identity (Either e a)
    m
    {-# INLINE runExcept #-}

    -- | Map the unwrapped computation using the given function.
    --
    -- * @'runExcept' ('mapExcept' f m) = f ('runExcept' m)@
    mapExcept :: (Either e a -> Either e' b)
            -> Except e a
            -> Except e' b
    mapExcept :: forall e a e' b.
    (Either e a -> Either e' b) -> Except e a -> Except e' b
    mapExcept Either e a -> Either e' b
    f = forall (m :: * -> *) e a (n :: * -> *) e' b.
    (m (Either e a) -> n (Either e' b))
    -> ExceptT e m a -> ExceptT e' n b
    mapExceptT (forall a. a -> Identity a
    Identity forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Either e a -> Either e' b
    f forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Identity a -> a
    runIdentity)
    {-# INLINE mapExcept #-}

    -- | Transform any exceptions thrown by the computation using the given
    -- function (a specialization of 'withExceptT').
    withExcept :: (e -> e') -> Except e a -> Except e' a
    withExcept :: forall e e' a. (e -> e') -> Except e a -> Except e' a
    withExcept = forall (m :: * -> *) e e' a.
    Functor m =>
    (e -> e') -> ExceptT e m a -> ExceptT e' m a
    withExceptT
    {-# INLINE withExcept #-}

    -- | A monad transformer that adds exceptions to other monads.
    --
    -- @ExceptT@ constructs a monad parameterized over two things:
    --
    -- * e - The exception type.
    --
    -- * m - The inner monad.
    --
    -- The 'return' function yields a computation that produces the given
    -- value, while @>>=@ sequences two subcomputations, exiting on the
    -- first exception.
    newtype ExceptT e m a = ExceptT (m (Either e a))

    instance (Eq e, Eq1 m) => Eq1 (ExceptT e m) where
        liftEq :: forall a b.
    (a -> b -> Bool) -> ExceptT e m a -> ExceptT e m b -> Bool
    liftEq a -> b -> Bool
    eq (ExceptT m (Either e a)
    x) (ExceptT m (Either e b)
    y) = forall (f :: * -> *) a b.
    Eq1 f =>
    (a -> b -> Bool) -> f a -> f b -> Bool
    liftEq (forall (f :: * -> *) a b.
    Eq1 f =>
    (a -> b -> Bool) -> f a -> f b -> Bool
    liftEq a -> b -> Bool
    eq) m (Either e a)
    x m (Either e b)
    y
        {-# INLINE liftEq #-}

    instance (Ord e, Ord1 m) => Ord1 (ExceptT e m) where
        liftCompare :: forall a b.
    (a -> b -> Ordering) -> ExceptT e m a -> ExceptT e m b -> Ordering
    liftCompare a -> b -> Ordering
    comp (ExceptT m (Either e a)
    x) (ExceptT m (Either e b)
    y) =
            forall (f :: * -> *) a b.
    Ord1 f =>
    (a -> b -> Ordering) -> f a -> f b -> Ordering
    liftCompare (forall (f :: * -> *) a b.
    Ord1 f =>
    (a -> b -> Ordering) -> f a -> f b -> Ordering
    liftCompare a -> b -> Ordering
    comp) m (Either e a)
    x m (Either e b)
    y
        {-# INLINE liftCompare #-}

    instance (Read e, Read1 m) => Read1 (ExceptT e m) where
        liftReadsPrec :: forall a.
    (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (ExceptT e m a)
    liftReadsPrec Int -> ReadS a
    rp ReadS [a]
    rl = forall a. (String -> ReadS a) -> Int -> ReadS a
    readsData forall a b. (a -> b) -> a -> b
    $
            forall a t.
    (Int -> ReadS a) -> String -> (a -> t) -> String -> ReadS t
    readsUnaryWith (forall (f :: * -> *) a.
    Read1 f =>
    (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a)
    liftReadsPrec Int -> ReadS (Either e a)
    rp' ReadS [Either e a]
    rl') String
    "ExceptT" forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT
          where
            rp' :: Int -> ReadS (Either e a)
    rp' = forall (f :: * -> *) a.
    Read1 f =>
    (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a)
    liftReadsPrec Int -> ReadS a
    rp ReadS [a]
    rl
            rl' :: ReadS [Either e a]
    rl' = forall (f :: * -> *) a.
    Read1 f =>
    (Int -> ReadS a) -> ReadS [a] -> ReadS [f a]
    liftReadList Int -> ReadS a
    rp ReadS [a]
    rl

    instance (Show e, Show1 m) => Show1 (ExceptT e m) where
        liftShowsPrec :: forall a.
    (Int -> a -> ShowS)
    -> ([a] -> ShowS) -> Int -> ExceptT e m a -> ShowS
    liftShowsPrec Int -> a -> ShowS
    sp [a] -> ShowS
    sl Int
    d (ExceptT m (Either e a)
    m) =
            forall a. (Int -> a -> ShowS) -> String -> Int -> a -> ShowS
    showsUnaryWith (forall (f :: * -> *) a.
    Show1 f =>
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
    liftShowsPrec Int -> Either e a -> ShowS
    sp' [Either e a] -> ShowS
    sl') String
    "ExceptT" Int
    d m (Either e a)
    m
          where
            sp' :: Int -> Either e a -> ShowS
    sp' = forall (f :: * -> *) a.
    Show1 f =>
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
    liftShowsPrec Int -> a -> ShowS
    sp [a] -> ShowS
    sl
            sl' :: [Either e a] -> ShowS
    sl' = forall (f :: * -> *) a.
    Show1 f =>
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> [f a] -> ShowS
    liftShowList Int -> a -> ShowS
    sp [a] -> ShowS
    sl

    instance (Eq e, Eq1 m, Eq a) => Eq (ExceptT e m a)
        where == :: ExceptT e m a -> ExceptT e m a -> Bool
    (==) = forall (f :: * -> *) a. (Eq1 f, Eq a) => f a -> f a -> Bool
    eq1
    instance (Ord e, Ord1 m, Ord a) => Ord (ExceptT e m a)
        where compare :: ExceptT e m a -> ExceptT e m a -> Ordering
    compare = forall (f :: * -> *) a. (Ord1 f, Ord a) => f a -> f a -> Ordering
    compare1
    instance (Read e, Read1 m, Read a) => Read (ExceptT e m a) where
        readsPrec :: Int -> ReadS (ExceptT e m a)
    readsPrec = forall (f :: * -> *) a. (Read1 f, Read a) => Int -> ReadS (f a)
    readsPrec1
    instance (Show e, Show1 m, Show a) => Show (ExceptT e m a) where
        showsPrec :: Int -> ExceptT e m a -> ShowS
    showsPrec = forall (f :: * -> *) a. (Show1 f, Show a) => Int -> f a -> ShowS
    showsPrec1

    -- | The inverse of 'ExceptT'.
    runExceptT :: ExceptT e m a -> m (Either e a)
    runExceptT :: forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT (ExceptT m (Either e a)
    m) = m (Either e a)
    m
    {-# INLINE runExceptT #-}

    -- | Map the unwrapped computation using the given function.
    --
    -- * @'runExceptT' ('mapExceptT' f m) = f ('runExceptT' m)@
    mapExceptT :: (m (Either e a) -> n (Either e' b))
            -> ExceptT e m a
            -> ExceptT e' n b
    mapExceptT :: forall (m :: * -> *) e a (n :: * -> *) e' b.
    (m (Either e a) -> n (Either e' b))
    -> ExceptT e m a -> ExceptT e' n b
    mapExceptT m (Either e a) -> n (Either e' b)
    f ExceptT e m a
    m = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ m (Either e a) -> n (Either e' b)
    f (forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT ExceptT e m a
    m)
    {-# INLINE mapExceptT #-}

    -- | Transform any exceptions thrown by the computation using the
    -- given function.
    withExceptT :: (Functor m) => (e -> e') -> ExceptT e m a -> ExceptT e' m a
    withExceptT :: forall (m :: * -> *) e e' a.
    Functor m =>
    (e -> e') -> ExceptT e m a -> ExceptT e' m a
    withExceptT e -> e'
    f = forall (m :: * -> *) e a (n :: * -> *) e' b.
    (m (Either e a) -> n (Either e' b))
    -> ExceptT e m a -> ExceptT e' n b
    mapExceptT forall a b. (a -> b) -> a -> b
    $ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap forall a b. (a -> b) -> a -> b
    $ forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (forall a b. a -> Either a b
    Left forall b c a. (b -> c) -> (a -> b) -> a -> c
    . e -> e'
    f) forall a b. b -> Either a b
    Right
    {-# INLINE withExceptT #-}

    instance (Functor m) => Functor (ExceptT e m) where
        fmap :: forall a b. (a -> b) -> ExceptT e m a -> ExceptT e m b
    fmap a -> b
    f = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT
        {-# INLINE fmap #-}

    instance (Foldable f) => Foldable (ExceptT e f) where
        foldMap :: forall m a. Monoid m => (a -> m) -> ExceptT e f a -> m
    foldMap a -> m
    f (ExceptT f (Either e a)
    a) = forall (t :: * -> *) m a.
    (Foldable t, Monoid m) =>
    (a -> m) -> t a -> m
    foldMap (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (forall a b. a -> b -> a
    const forall a. Monoid a => a
    mempty) a -> m
    f) f (Either e a)
    a
        {-# INLINE foldMap #-}

    instance (Traversable f) => Traversable (ExceptT e f) where
        traverse :: forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> ExceptT e f a -> f (ExceptT e f b)
    traverse a -> f b
    f (ExceptT f (Either e a)
    a) =
            forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> forall (t :: * -> *) (f :: * -> *) a b.
    (Traversable t, Applicative f) =>
    (a -> f b) -> t a -> f (t b)
    traverse (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (forall (f :: * -> *) a. Applicative f => a -> f a
    pure forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. a -> Either a b
    Left) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap forall a b. b -> Either a b
    Right forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> f b
    f)) f (Either e a)
    a
        {-# INLINE traverse #-}

    instance (Functor m, Monad m) => Applicative (ExceptT e m) where
        pure :: forall a. a -> ExceptT e m a
    pure a
    a = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. b -> Either a b
    Right a
    a)
        {-# INLINE pure #-}
        ExceptT m (Either e (a -> b))
    f <*> :: forall a b. ExceptT e m (a -> b) -> ExceptT e m a -> ExceptT e m b
    <*> ExceptT m (Either e a)
    v = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ do
            Either e (a -> b)
    mf <- m (Either e (a -> b))
    f
            case Either e (a -> b)
    mf of
                Left e
    e -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. a -> Either a b
    Left e
    e)
                Right a -> b
    k -> do
                    Either e a
    mv <- m (Either e a)
    v
                    case Either e a
    mv of
                        Left e
    e -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. a -> Either a b
    Left e
    e)
                        Right a
    x -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. b -> Either a b
    Right (a -> b
    k a
    x))
        {-# INLINEABLE (<*>) #-}
        ExceptT e m a
    m *> :: forall a b. ExceptT e m a -> ExceptT e m b -> ExceptT e m b
    *> ExceptT e m b
    k = ExceptT e m a
    m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \a
    _ -> ExceptT e m b
    k
        {-# INLINE (*>) #-}

    instance (Functor m, Monad m, Monoid e) => Alternative (ExceptT e m) where
        empty :: forall a. ExceptT e m a
    empty = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. a -> Either a b
    Left forall a. Monoid a => a
    mempty)
        {-# INLINE empty #-}
        ExceptT m (Either e a)
    mx <|> :: forall a. ExceptT e m a -> ExceptT e m a -> ExceptT e m a
    <|> ExceptT m (Either e a)
    my = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ do
            Either e a
    ex <- m (Either e a)
    mx
            case Either e a
    ex of
                Left e
    e -> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (forall a b. a -> Either a b
    Left forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Monoid a => a -> a -> a
    mappend e
    e) forall a b. b -> Either a b
    Right) m (Either e a)
    my
                Right a
    x -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. b -> Either a b
    Right a
    x)
        {-# INLINEABLE (<|>) #-}

    instance (Monad m) => Monad (ExceptT e m) where
    #if !(MIN_VERSION_base(4,8,0))
        return a = ExceptT $ return (Right a)
        {-# INLINE return #-}
    #endif
        ExceptT e m a
    m >>= :: forall a b. ExceptT e m a -> (a -> ExceptT e m b) -> ExceptT e m b
    >>= a -> ExceptT e m b
    k = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ do
            Either e a
    a <- forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT ExceptT e m a
    m
            case Either e a
    a of
                Left e
    e -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. a -> Either a b
    Left e
    e)
                Right a
    x -> forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT (a -> ExceptT e m b
    k a
    x)
        {-# INLINE (>>=) #-}
    #if !(MIN_VERSION_base(4,13,0))
        fail = ExceptT . fail
        {-# INLINE fail #-}
    #endif

    #if MIN_VERSION_base(4,9,0)
    instance (Fail.MonadFail m) => Fail.MonadFail (ExceptT e m) where
        fail :: forall a. String -> ExceptT e m a
    fail = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (m :: * -> *) a. MonadFail m => String -> m a
    Fail.fail
        {-# INLINE fail #-}
    #endif

    instance (Monad m, Monoid e) => MonadPlus (ExceptT e m) where
        mzero :: forall a. ExceptT e m a
    mzero = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. a -> Either a b
    Left forall a. Monoid a => a
    mempty)
        {-# INLINE mzero #-}
        ExceptT m (Either e a)
    mx mplus :: forall a. ExceptT e m a -> ExceptT e m a -> ExceptT e m a
    `mplus` ExceptT m (Either e a)
    my = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ do
            Either e a
    ex <- m (Either e a)
    mx
            case Either e a
    ex of
                Left e
    e -> forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (forall a b. a -> Either a b
    Left forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a. Monoid a => a -> a -> a
    mappend e
    e) forall a b. b -> Either a b
    Right) m (Either e a)
    my
                Right a
    x -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. b -> Either a b
    Right a
    x)
        {-# INLINEABLE mplus #-}

    instance (MonadFix m) => MonadFix (ExceptT e m) where
        mfix :: forall a. (a -> ExceptT e m a) -> ExceptT e m a
    mfix a -> ExceptT e m a
    f = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT (forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
    mfix (forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> ExceptT e m a
    f forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (forall a b. a -> b -> a
    const forall {a}. a
    bomb) forall a. a -> a
    id))
          where bomb :: a
    bomb = forall a. HasCallStack => String -> a
    error String
    "mfix (ExceptT): inner computation returned Left value"
        {-# INLINE mfix #-}

    instance MonadTrans (ExceptT e) where
        lift :: forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
    lift = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM forall a b. b -> Either a b
    Right
        {-# INLINE lift #-}

    instance (MonadIO m) => MonadIO (ExceptT e m) where
        liftIO :: forall a. IO a -> ExceptT e m a
    liftIO = forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO
        {-# INLINE liftIO #-}

    #if MIN_VERSION_base(4,4,0)
    instance (MonadZip m) => MonadZip (ExceptT e m) where
        mzipWith :: forall a b c.
    (a -> b -> c) -> ExceptT e m a -> ExceptT e m b -> ExceptT e m c
    mzipWith a -> b -> c
    f (ExceptT m (Either e a)
    a) (ExceptT m (Either e b)
    b) = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *) a b c.
    MonadZip m =>
    (a -> b -> c) -> m a -> m b -> m c
    mzipWith (forall (f :: * -> *) a b c.
    Applicative f =>
    (a -> b -> c) -> f a -> f b -> f c
    liftA2 a -> b -> c
    f) m (Either e a)
    a m (Either e b)
    b
        {-# INLINE mzipWith #-}
    #endif

    #if MIN_VERSION_base(4,12,0)
    instance Contravariant m => Contravariant (ExceptT e m) where
        contramap :: forall a' a. (a' -> a) -> ExceptT e m a -> ExceptT e m a'
    contramap a' -> a
    f = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (f :: * -> *) a' a.
    Contravariant f =>
    (a' -> a) -> f a -> f a'
    contramap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a' -> a
    f) forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT
        {-# INLINE contramap #-}
    #endif

    -- | Signal an exception value @e@.
    --
    -- * @'runExceptT' ('throwE' e) = 'return' ('Left' e)@
    --
    -- * @'throwE' e >>= m = 'throwE' e@
    throwE :: (Monad m) => e -> ExceptT e m a
    throwE :: forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
    throwE = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall (m :: * -> *) a. Monad m => a -> m a
    return forall b c a. (b -> c) -> (a -> b) -> a -> c
    . forall a b. a -> Either a b
    Left
    {-# INLINE throwE #-}

    -- | Handle an exception.
    --
    -- * @'catchE' ('lift' m) h = 'lift' m@
    --
    -- * @'catchE' ('throwE' e) h = h e@
    catchE :: (Monad m) =>
        ExceptT e m a               -- ^ the inner computation
        -> (e -> ExceptT e' m a)    -- ^ a handler for exceptions in the inner
                                    -- computation
        -> ExceptT e' m a
    ExceptT e m a
    m catchE :: forall (m :: * -> *) e a e'.
    Monad m =>
    ExceptT e m a -> (e -> ExceptT e' m a) -> ExceptT e' m a
    `catchE` e -> ExceptT e' m a
    h = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ do
        Either e a
    a <- forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT ExceptT e m a
    m
        case Either e a
    a of
            Left  e
    l -> forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT (e -> ExceptT e' m a
    h e
    l)
            Right a
    r -> forall (m :: * -> *) a. Monad m => a -> m a
    return (forall a b. b -> Either a b
    Right a
    r)
    {-# INLINE catchE #-}

    -- | Lift a @callCC@ operation to the new monad.
    liftCallCC :: CallCC m (Either e a) (Either e b) -> CallCC (ExceptT e m) a b
    liftCallCC :: forall (m :: * -> *) e a b.
    CallCC m (Either e a) (Either e b) -> CallCC (ExceptT e m) a b
    liftCallCC CallCC m (Either e a) (Either e b)
    callCC (a -> ExceptT e m b) -> ExceptT e m a
    f = forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $
        CallCC m (Either e a) (Either e b)
    callCC forall a b. (a -> b) -> a -> b
    $ \ Either e a -> m (Either e b)
    c ->
        forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT ((a -> ExceptT e m b) -> ExceptT e m a
    f (\ a
    a -> forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT forall a b. (a -> b) -> a -> b
    $ Either e a -> m (Either e b)
    c (forall a b. b -> Either a b
    Right a
    a)))
    {-# INLINE liftCallCC #-}

    -- | Lift a @listen@ operation to the new monad.
    liftListen :: (Monad m) => Listen w m (Either e a) -> Listen w (ExceptT e m) a
    liftListen :: forall (m :: * -> *) w e a.
    Monad m =>
    Listen w m (Either e a) -> Listen w (ExceptT e m) a
    liftListen Listen w m (Either e a)
    listen = forall (m :: * -> *) e a (n :: * -> *) e' b.
    (m (Either e a) -> n (Either e' b))
    -> ExceptT e m a -> ExceptT e' n b
    mapExceptT forall a b. (a -> b) -> a -> b
    $ \ m (Either e a)
    m -> do
        (Either e a
    a, w
    w) <- Listen w m (Either e a)
    listen m (Either e a)
    m
        forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $! forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\ a
    r -> (a
    r, w
    w)) Either e a
    a
    {-# INLINE liftListen #-}

    -- | Lift a @pass@ operation to the new monad.
    liftPass :: (Monad m) => Pass w m (Either e a) -> Pass w (ExceptT e m) a
    liftPass :: forall (m :: * -> *) w e a.
    Monad m =>
    Pass w m (Either e a) -> Pass w (ExceptT e m) a
    liftPass Pass w m (Either e a)
    pass = forall (m :: * -> *) e a (n :: * -> *) e' b.
    (m (Either e a) -> n (Either e' b))
    -> ExceptT e m a -> ExceptT e' n b
    mapExceptT forall a b. (a -> b) -> a -> b
    $ \ m (Either e (a, w -> w))
    m -> Pass w m (Either e a)
    pass forall a b. (a -> b) -> a -> b
    $ do
        Either e (a, w -> w)
    a <- m (Either e (a, w -> w))
    m
        forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $! case Either e (a, w -> w)
    a of
            Left e
    l -> (forall a b. a -> Either a b
    Left e
    l, forall a. a -> a
    id)
            Right (a
    r, w -> w
    f) -> (forall a b. b -> Either a b
    Right a
    r, w -> w
    f)
    {-# INLINE liftPass #-}