    {-# LANGUAGE CPP #-}

    {-|
    Module      : Control.FromSum
    Copyright   : (c) Dennis Gosnell, 2016
    License     : BSD-style (see LICENSE file)
    Maintainer  : cdep.illabout@gmail.com
    Stability   : experimental
    Portability : POSIX

    This Haskell module exports various \"from\" functions for 'Either' and
    'Maybe'.
    -}
    module Control.FromSum
      ( -- * Monadic in return value
        fromEitherM
      , fromEitherOrM
      , fromEitherM_
      , fromEitherOrM_
      , fromMaybeM
      , fromMaybeOrM
      , fromMaybeM_
      , fromMaybeOrM_
        -- * Monadic in both return and sum-type value
      , fromEitherMM
      , fromEitherOrMM
      , fromMaybeMM
      , fromMaybeOrMM
        -- * Completely non-monadic functions
      , fromEither
      , fromEitherOr
      , fromMaybe
      , fromMaybeOr
        -- * Converting from 'Maybe' to 'Either'
      , maybeToEither
      , maybeToEitherOr
      , eitherToMaybe
        -- * Collapsing funtions
      , collapseEither
      , collapseExceptT
      , collapseErrExceptT
      , -- * Converting to 'ExceptT'
        liftEitherExceptT
      , fromEitherExceptT
      , fromEitherOrExceptT
      , fromEitherMExceptT
      , fromEitherOrMExceptT
      , fromMaybeExceptT
      , fromMaybeOrExceptT
      , fromMaybeMExceptT
      , fromMaybeOrMExceptT
      , guardExceptT
      , guardMExceptT
        -- * Example converting to 'ExceptT'
        -- $exampleExceptT
        -- * Doctests
        -- $setup
      ) where

    #if __GLASGOW_HASKELL__ < 710
    -- We don't need this import for GHC 7.10 as it exports all required functions
    -- from Prelude
    import Control.Applicative
    #endif
    import Control.Monad ((<=<))
    import Control.Monad.Trans.Class (lift)
    import Control.Monad.Trans.Except (ExceptT(ExceptT), runExceptT, throwE)
    import Data.Maybe (fromMaybe)

    -- $setup
    --
    -- The following is setup code for doctests in this module.
    --
    -- >>> import Data.Functor.Identity (Identity(Identity))

    -- | A monadic version of 'fromEither'.
    --
    -- @
    --  'fromEitherM' leftAction === 'either' leftAction 'pure'
    -- @
    --
    -- >>> fromEitherM (\s -> [length s]) $ Right 5
    -- [5]
    -- >>> fromEitherM (\s -> [length s]) $ Left ("foo" :: String)
    -- [3]
    fromEitherM
      :: Applicative m
      => (e -> m a) -> Either e a -> m a
    fromEitherM :: forall (m :: * -> *) e a.
    Applicative m =>
    (e -> m a) -> Either e a -> m a
    fromEitherM e -> m a
    leftAction = (e -> m a) -> (a -> m a) -> Either e a -> m a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either e -> m a
    leftAction a -> m a
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    -- | A 'flip'ed version of 'fromEitherM'.
    --
    -- >>> fromEitherOrM (Right 5) $ \s -> [length s]
    -- [5]
    --
    -- This can be nice to use as an error handler.
    --
    -- >>> fromEitherOrM (Right 5) $ \s -> putStrLn ("error: " ++ s) >> undefined
    -- 5
    -- >>> fromEitherOrM (Left "foo") $ \s -> putStrLn ("error: " ++ s) >> undefined
    -- error: foo
    -- ...
    fromEitherOrM
      :: Applicative m
      => Either e a -> (e -> m a) -> m a
    fromEitherOrM :: forall (m :: * -> *) e a.
    Applicative m =>
    Either e a -> (e -> m a) -> m a
    fromEitherOrM = ((e -> m a) -> Either e a -> m a)
    -> Either e a -> (e -> m a) -> m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (e -> m a) -> Either e a -> m a
    forall (m :: * -> *) e a.
    Applicative m =>
    (e -> m a) -> Either e a -> m a
    fromEitherM

    -- | Similar to 'fromEitherM', but only run the monadic 'leftAction' if the
    -- 'Either' argument is 'Left'.  Otherwise, return 'pure' 'mempty'.
    --
    -- @
    --  'fromEitherM_' leftAction === 'either' leftAction ('const' '$' 'pure' 'mempty')
    -- @
    --
    -- >>> fromEitherM_ (\err -> putStrLn err >> pure "bye") $ Right 5
    -- ""
    -- >>> fromEitherM_ (\err -> putStrLn err >> pure "bye") $ Left "there was an error"
    -- there was an error
    -- "bye"
    --
    -- This can be convenient when you want to run some sort of logging function
    -- whenever an 'Either' is 'Left'.  If you imagine the logging function is
    -- @b -> 'IO' '()'@, then the effective type of 'fromEitherM_' becomes
    -- @'fromEitherM_' :: (e -> 'IO' '()') -> 'Either' e a -> 'IO' '()'@, because
    -- '()' has a 'Monoid' instance, and 'IO', has an 'Applicative' instance.
    --
    -- >>> fromEitherM_ putStrLn $ Left "there was an error"
    -- there was an error
    fromEitherM_
      :: (Applicative m, Monoid b)
      => (e -> m b) -> Either e a -> m b
    fromEitherM_ :: forall (m :: * -> *) b e a.
    (Applicative m, Monoid b) =>
    (e -> m b) -> Either e a -> m b
    fromEitherM_ e -> m b
    leftAction = (e -> m b) -> (a -> m b) -> Either e a -> m b
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either e -> m b
    leftAction (m b -> a -> m b
    forall a b. a -> b -> a
    const (m b -> a -> m b) -> m b -> a -> m b
    forall a b. (a -> b) -> a -> b
    $ b -> m b
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure b
    forall a. Monoid a => a
    mempty)

    -- | A 'flip'ed version of 'fromEitherM_'.
    fromEitherOrM_
      :: (Applicative m, Monoid b)
      => Either e a -> (e -> m b) -> m b
    fromEitherOrM_ :: forall (m :: * -> *) b e a.
    (Applicative m, Monoid b) =>
    Either e a -> (e -> m b) -> m b
    fromEitherOrM_ = ((e -> m b) -> Either e a -> m b)
    -> Either e a -> (e -> m b) -> m b
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (e -> m b) -> Either e a -> m b
    forall (m :: * -> *) b e a.
    (Applicative m, Monoid b) =>
    (e -> m b) -> Either e a -> m b
    fromEitherM_

    -- | A monadic version of 'fromMaybe'.
    --
    -- @
    --  'fromMaybeM' nothingAction === 'maybe' nothingAction 'pure'
    -- @
    --
    -- >>> fromMaybeM [] $ Just 5
    -- [5]
    -- >>> fromMaybeM [] Nothing
    -- []
    fromMaybeM
      :: Applicative m
      => m a -> Maybe a -> m a
    fromMaybeM :: forall (m :: * -> *) a. Applicative m => m a -> Maybe a -> m a
    fromMaybeM m a
    nothingAction = m a -> (a -> m a) -> Maybe a -> m a
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m a
    nothingAction a -> m a
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    -- | A 'flip'ed version of 'fromMaybeM'.
    --
    -- >>> fromMaybeOrM (Just 5) []
    -- [5]
    --
    -- This can be nice to use as an error handler.
    --
    -- >>> fromMaybeOrM (Just 5) $ putStrLn "some error occurred" >> undefined
    -- 5
    -- >>> fromMaybeOrM (Nothing) $ putStrLn "some error occurred" >> undefined
    -- some error occurred
    -- ...
    fromMaybeOrM
      :: Applicative m
      => Maybe a -> m a -> m a
    fromMaybeOrM :: forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
    fromMaybeOrM = (m a -> Maybe a -> m a) -> Maybe a -> m a -> m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip m a -> Maybe a -> m a
    forall (m :: * -> *) a. Applicative m => m a -> Maybe a -> m a
    fromMaybeM

    -- | Similar to 'fromMaybeM', but only run the monadic 'nothingAction' if the
    -- 'Maybe' argument is 'Nothing'.  Otherwise, return 'pure' 'mempty'.
    --
    -- @
    --  'fromMaybeM_' nothingAction === 'maybe' nothingAction ('const' '$' 'pure' 'mempty')
    -- @
    --
    -- >>> fromMaybeM_ (putStrLn "hello" >> pure "bye") $ Just 5
    -- ""
    -- >>> fromMaybeM_ (putStrLn "hello" >> pure "bye") Nothing
    -- hello
    -- "bye"
    --
    -- This can be convenient when you want to run some sort of logging function
    -- whenever a 'Maybe' is 'Nothing'.  If you imagine the logging function is
    -- @'IO' '()'@, then the effective type of 'fromMaybeM_' becomes
    -- @'fromMaybeM_' :: 'IO' '()' -> 'Maybe' a -> 'IO' '()'@, because '()' has a
    -- 'Monoid' instance, and 'IO', has an 'Applicative' instance.
    --
    -- >>> fromMaybeM_ (putStrLn "hello") Nothing
    -- hello
    fromMaybeM_
      :: (Applicative m, Monoid b)
      => m b -> Maybe a -> m b
    fromMaybeM_ :: forall (m :: * -> *) b a.
    (Applicative m, Monoid b) =>
    m b -> Maybe a -> m b
    fromMaybeM_ m b
    nothingAction = m b -> (a -> m b) -> Maybe a -> m b
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe m b
    nothingAction (m b -> a -> m b
    forall a b. a -> b -> a
    const (m b -> a -> m b) -> m b -> a -> m b
    forall a b. (a -> b) -> a -> b
    $ b -> m b
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure b
    forall a. Monoid a => a
    mempty)

    -- | A 'flip'ed version of 'fromMaybeM'.
    fromMaybeOrM_
      :: (Applicative m, Monoid b)
      => Maybe a -> m b -> m b
    fromMaybeOrM_ :: forall (m :: * -> *) b a.
    (Applicative m, Monoid b) =>
    Maybe a -> m b -> m b
    fromMaybeOrM_ = (m b -> Maybe a -> m b) -> Maybe a -> m b -> m b
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip m b -> Maybe a -> m b
    forall (m :: * -> *) b a.
    (Applicative m, Monoid b) =>
    m b -> Maybe a -> m b
    fromMaybeM_

    -- | Similar to 'fromEitherM' but the 'Either' argument is also a monadic value.
    --
    -- >>> fromEitherMM (\s -> [length s]) [Right 5, Right 10]
    -- [5,10]
    -- >>> fromEitherMM (\s -> [length s]) [Left ("foo" :: String), Right 100]
    -- [3,100]
    --
    -- __NOTE__: I don't particularly like the name of this function.  If you have a
    -- suggestion for a better name, please submit a PR or issue.
    fromEitherMM
      :: Monad m
      => (e -> m a) -> m (Either e a) -> m a
    fromEitherMM :: forall (m :: * -> *) e a.
    Monad m =>
    (e -> m a) -> m (Either e a) -> m a
    fromEitherMM e -> m a
    eitherAction m (Either e a)
    mEither = (e -> m a) -> Either e a -> m a
    forall (m :: * -> *) e a.
    Applicative m =>
    (e -> m a) -> Either e a -> m a
    fromEitherM e -> m a
    eitherAction (Either e a -> m a) -> m (Either e a) -> m a
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< m (Either e a)
    mEither

    -- | A 'flip'ed version of 'fromEitherMM'.
    fromEitherOrMM
      :: Monad m
      => m (Either e a) -> (e -> m a) -> m a
    fromEitherOrMM :: forall (m :: * -> *) e a.
    Monad m =>
    m (Either e a) -> (e -> m a) -> m a
    fromEitherOrMM = ((e -> m a) -> m (Either e a) -> m a)
    -> m (Either e a) -> (e -> m a) -> m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (e -> m a) -> m (Either e a) -> m a
    forall (m :: * -> *) e a.
    Monad m =>
    (e -> m a) -> m (Either e a) -> m a
    fromEitherMM

    -- | Similar to 'fromMaybeM' but the 'Maybe' argument is also a monadic value.
    --
    -- >>> fromMaybeMM [] [Just 6, Just 5]
    -- [6,5]
    -- >>> fromMaybeMM [] [Just 6, Nothing, Just 7]
    -- [6,7]
    --
    -- __NOTE__: I don't particularly like the name of this function.  If you have a
    -- suggestion for a better name, please submit a PR or issue.
    fromMaybeMM
      :: Monad m
      => m a -> m (Maybe a) -> m a
    fromMaybeMM :: forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
    fromMaybeMM m a
    nothingAction m (Maybe a)
    mMaybe = m a -> Maybe a -> m a
    forall (m :: * -> *) a. Applicative m => m a -> Maybe a -> m a
    fromMaybeM m a
    nothingAction (Maybe a -> m a) -> m (Maybe a) -> m a
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< m (Maybe a)
    mMaybe

    -- | A 'flip'ed version of 'fromMaybeMM'.
    fromMaybeOrMM
      :: Monad m
      => m (Maybe a) -> m a -> m a
    fromMaybeOrMM :: forall (m :: * -> *) a. Monad m => m (Maybe a) -> m a -> m a
    fromMaybeOrMM = (m a -> m (Maybe a) -> m a) -> m (Maybe a) -> m a -> m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip m a -> m (Maybe a) -> m a
    forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
    fromMaybeMM

    -- | Similar to 'fromMaybe'.
    --
    -- >>> fromEither show $ Left 5
    -- "5"
    -- >>> fromEither show $ Right "hello"
    -- "hello"
    fromEither :: (e -> a) -> Either e a -> a
    fromEither :: forall e a. (e -> a) -> Either e a -> a
    fromEither e -> a
    f = (e -> a) -> (a -> a) -> Either e a -> a
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either e -> a
    f a -> a
    forall a. a -> a
    id

    -- | A 'flip'ed version of 'fromEither'.
    fromEitherOr :: Either e a -> (e -> a) -> a
    fromEitherOr :: forall e a. Either e a -> (e -> a) -> a
    fromEitherOr = ((e -> a) -> Either e a -> a) -> Either e a -> (e -> a) -> a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (e -> a) -> Either e a -> a
    forall e a. (e -> a) -> Either e a -> a
    fromEither

    -- | A 'flip'ed version of 'fromMaybe'.
    fromMaybeOr :: Maybe a -> a -> a
    fromMaybeOr :: forall a. Maybe a -> a -> a
    fromMaybeOr = (a -> Maybe a -> a) -> Maybe a -> a -> a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip a -> Maybe a -> a
    forall a. a -> Maybe a -> a
    fromMaybe

    -- | Collapse an @'Either' a a@ to an @a@.  Defined as @'fromEither' 'id'@.
    --
    -- Note: Other libraries export this function as @fromEither@, but our
    -- 'fromEither' function is slightly more general.
    --
    -- >>> collapseEither (Right 3)
    -- 3
    -- >>> collapseEither (Left "hello")
    -- "hello"
    collapseEither :: Either a a -> a
    collapseEither :: forall a. Either a a -> a
    collapseEither = (a -> a) -> Either a a -> a
    forall e a. (e -> a) -> Either e a -> a
    fromEither a -> a
    forall a. a -> a
    id

    -- | Similar to 'collapseEither', but for 'ExceptT'.
    --
    -- >>> collapseExceptT (ExceptT $ pure (Right 3))
    -- 3
    -- >>> collapseExceptT (ExceptT $ pure (Left "hello"))
    -- "hello"
    collapseExceptT :: Monad m => ExceptT a m a -> m a
    collapseExceptT :: forall (m :: * -> *) a. Monad m => ExceptT a m a -> m a
    collapseExceptT = a -> m a
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (a -> m a) -> (Either a a -> a) -> Either a a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Either a a -> a
    forall a. Either a a -> a
    collapseEither (Either a a -> m a)
    -> (ExceptT a m a -> m (Either a a)) -> ExceptT a m a -> m a
    forall (m :: * -> *) b c a.
    Monad m =>
    (b -> m c) -> (a -> m b) -> a -> m c
    <=< ExceptT a m a -> m (Either a a)
    forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT

    -- | Collapse an 'ExceptT' where the error returns the same type as the whole
    -- computation.
    --
    -- >>> let exceptTOne = pure 3 :: ExceptT (IO Int) IO Int
    -- >>> collapseErrExceptT exceptTOne :: IO Int
    -- 3
    --
    -- This is helpful when writing short-circuiting computations where you
    -- throw errors that match the type of the underlying computation.
    --
    -- >>> :{
    -- let go :: Int -> ExceptT (IO ()) IO ()
    --     go x = do
    --       bar <-
    --         if x < 10
    --         then
    --           pure "hello"
    --         else
    --           throwE (putStrLn "Error occurred, x too big!")
    --       lift $ putStrLn $ bar ++ " world"
    -- :}
    --
    -- >>> collapseErrExceptT (go 100) :: IO ()
    -- Error occurred, x too big!
    -- >>> collapseErrExceptT (go 3) :: IO ()
    -- hello world
    --
    -- In this example, the error type in the 'ExceptT' is @'IO' ()@.
    -- This allows us to easily short-circuit the remaining computations.
    -- In this example, the remaining computation is just printing
    -- @bar '++' \" world\"@.
    collapseErrExceptT :: Monad m => ExceptT (m a) m a -> m a
    collapseErrExceptT :: forall (m :: * -> *) a. Monad m => ExceptT (m a) m a -> m a
    collapseErrExceptT ExceptT (m a) m a
    exceptT = do
      res <- ExceptT (m a) m a -> m (Either (m a) a)
    forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
    runExceptT ExceptT (m a) m a
    exceptT
      case res of
        Left m a
    errHandler -> m a
    errHandler
        Right a
    success -> a -> m a
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    success

    -- | Convert a 'Maybe' to an 'Either'.
    --
    -- If the 'Maybe' is 'Just', then return the value in 'Right'.
    --
    -- >>> maybeToEither 3 $ Just "hello"
    -- Right "hello"
    --
    -- If the 'Maybe' is 'Nothing', then use the given @e@ as 'Left'.
    --
    -- >>> maybeToEither 3 Nothing
    -- Left 3
    maybeToEither :: e -> Maybe a -> Either e a
    maybeToEither :: forall e a. e -> Maybe a -> Either e a
    maybeToEither e
    e Maybe a
    Nothing = e -> Either e a
    forall a b. a -> Either a b
    Left e
    e
    maybeToEither e
    _ (Just a
    a) = a -> Either e a
    forall a b. b -> Either a b
    Right a
    a

    -- | A 'flip'ed version of 'maybeToEither'.
    --
    -- >>> maybeToEitherOr (Just "hello") 3
    -- Right "hello"
    --
    -- >>> maybeToEitherOr Nothing 3
    -- Left 3
    maybeToEitherOr :: Maybe a -> e -> Either e a
    maybeToEitherOr :: forall a e. Maybe a -> e -> Either e a
    maybeToEitherOr = (e -> Maybe a -> Either e a) -> Maybe a -> e -> Either e a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip e -> Maybe a -> Either e a
    forall e a. e -> Maybe a -> Either e a
    maybeToEither

    -- | Convert an 'Either' to a 'Maybe'.
    --
    -- A 'Right' value becomes 'Just'.
    --
    -- >>> eitherToMaybe $ Right 3
    -- Just 3
    --
    -- A 'Left' value becomes 'Nothing'.
    --
    -- >>> eitherToMaybe $ Left "bye"
    -- Nothing
    eitherToMaybe :: Either e a -> Maybe a
    eitherToMaybe :: forall e a. Either e a -> Maybe a
    eitherToMaybe (Left e
    _) = Maybe a
    forall a. Maybe a
    Nothing
    eitherToMaybe (Right a
    a) = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a

    -- | Lift an 'Either' into an 'ExceptT'.
    --
    -- This is the same as 'Control.Monad.Except.liftEither', but the return type
    -- is specialized for 'ExceptT'.
    --
    -- >>> liftEitherExceptT (Right 3) :: ExceptT String Identity Int
    -- ExceptT (Identity (Right 3))
    --
    -- Note that if you want to lift @m ('Either' e a)@ to @'ExceptT' e m a@,
    -- just use 'ExceptT':
    --
    -- >>> action = Identity (Left "error") :: Identity (Either String Int)
    -- >>> ExceptT action :: ExceptT String Identity Int
    -- ExceptT (Identity (Left "error"))
    liftEitherExceptT :: Applicative m => Either e a -> ExceptT e m a
    liftEitherExceptT :: forall (m :: * -> *) e a.
    Applicative m =>
    Either e a -> ExceptT e m a
    liftEitherExceptT = m (Either e a) -> ExceptT e m a
    forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
    ExceptT (m (Either e a) -> ExceptT e m a)
    -> (Either e a -> m (Either e a)) -> Either e a -> ExceptT e m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Either e a -> m (Either e a)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    -- | Lift an 'Either' to an 'ExceptT' with a handler for transforming the error
    -- value.
    --
    -- If the input 'Either' is 'Right', then just return it like normal:
    --
    -- >>> let rightEither = Right () :: Either String ()
    -- >>> fromEitherExceptT (\str -> length str) rightEither :: ExceptT Int Identity ()
    -- ExceptT (Identity (Right ()))
    --
    -- If the input 'Either' is 'Left', then pass the value to the handler:
    --
    -- >>> let leftEither = Left "hello" :: Either String ()
    -- >>> fromEitherExceptT (\str -> length str) leftEither :: ExceptT Int Identity ()
    -- ExceptT (Identity (Left 5))
    fromEitherExceptT :: Monad m => (e -> x) -> Either e a -> ExceptT x m a
    fromEitherExceptT :: forall (m :: * -> *) e x a.
    Monad m =>
    (e -> x) -> Either e a -> ExceptT x m a
    fromEitherExceptT e -> x
    handler Either e a
    eith = (e -> x) -> m (Either e a) -> ExceptT x m a
    forall (m :: * -> *) e x a.
    Monad m =>
    (e -> x) -> m (Either e a) -> ExceptT x m a
    fromEitherMExceptT e -> x
    handler (Either e a -> m (Either e a)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Either e a
    eith)

    -- | Just like 'fromEitherExceptT', but the arguments are flipped.
    fromEitherOrExceptT :: Monad m => Either e a -> (e -> x) -> ExceptT x m a
    fromEitherOrExceptT :: forall (m :: * -> *) e a x.
    Monad m =>
    Either e a -> (e -> x) -> ExceptT x m a
    fromEitherOrExceptT Either e a
    eith e -> x
    handler = (e -> x) -> Either e a -> ExceptT x m a
    forall (m :: * -> *) e x a.
    Monad m =>
    (e -> x) -> Either e a -> ExceptT x m a
    fromEitherExceptT e -> x
    handler Either e a
    eith

    -- | Similar to 'fromEitherExceptT' but the 'Either' value is lifted in a
    -- 'Monad'.
    --
    -- >>> let identityLeft = Identity (Left "hello") :: Identity (Either String ())
    -- >>> fromEitherMExceptT (\str -> length str) identityLeft :: ExceptT Int Identity ()
    -- ExceptT (Identity (Left 5))
    --
    -- This is similar to 'Control.Monad.Trans.Except.withExceptT', but the second
    -- argument is the unwrapped 'ExceptT' computation.
    fromEitherMExceptT :: Monad m => (e -> x) -> m (Either e a) -> ExceptT x m a
    fromEitherMExceptT :: forall (m :: * -> *) e x a.
    Monad m =>
    (e -> x) -> m (Either e a) -> ExceptT x m a
    fromEitherMExceptT e -> x
    handler m (Either e a)
    action = do
      res <- m (Either e a) -> ExceptT x m (Either e a)
    forall (m :: * -> *) a. Monad m => m a -> ExceptT x m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m (Either e a)
    action
      case res of
        Left e
    e -> x -> ExceptT x m a
    forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
    throwE (e -> x
    handler e
    e)
        Right a
    a -> a -> ExceptT x m a
    forall a. a -> ExceptT x m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    a

    -- | Just like 'fromEitherOrMExceptT', but the arguments are flipped.
    fromEitherOrMExceptT :: Monad m => m (Either e a) -> (e -> x) -> ExceptT x m a
    fromEitherOrMExceptT :: forall (m :: * -> *) e a x.
    Monad m =>
    m (Either e a) -> (e -> x) -> ExceptT x m a
    fromEitherOrMExceptT m (Either e a)
    action e -> x
    handler = (e -> x) -> m (Either e a) -> ExceptT x m a
    forall (m :: * -> *) e x a.
    Monad m =>
    (e -> x) -> m (Either e a) -> ExceptT x m a
    fromEitherMExceptT e -> x
    handler m (Either e a)
    action

    -- | Lift a 'Maybe' to an 'ExceptT' with a default value for the case when
    -- the 'Maybe' is 'Nothing'.
    --
    -- If the 'Maybe' is 'Just', then just return the value like normal:
    --
    -- >>> let justVal = Just True :: Maybe Bool
    -- >>> fromMaybeExceptT 5 justVal :: ExceptT Int Identity Bool
    -- ExceptT (Identity (Right True))
    --
    -- If the 'Maybe' is 'Nothing', then use the default value as the error value:
    --
    -- >>> let nothingVal = Nothing :: Maybe Bool
    -- >>> fromMaybeExceptT 5 nothingVal :: ExceptT Int Identity Bool
    -- ExceptT (Identity (Left 5))
    fromMaybeExceptT :: Monad m => x -> Maybe a -> ExceptT x m a
    fromMaybeExceptT :: forall (m :: * -> *) x a. Monad m => x -> Maybe a -> ExceptT x m a
    fromMaybeExceptT x
    handler Maybe a
    mayb = x -> m (Maybe a) -> ExceptT x m a
    forall (m :: * -> *) x a.
    Monad m =>
    x -> m (Maybe a) -> ExceptT x m a
    fromMaybeMExceptT x
    handler (Maybe a -> m (Maybe a)
    forall a. a -> m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe a
    mayb)

    -- | Just like 'fromMaybeExceptT' but with the arguments flipped.
    fromMaybeOrExceptT :: Monad m => Maybe a -> x -> ExceptT x m a
    fromMaybeOrExceptT :: forall (m :: * -> *) a x. Monad m => Maybe a -> x -> ExceptT x m a
    fromMaybeOrExceptT = (x -> Maybe a -> ExceptT x m a) -> Maybe a -> x -> ExceptT x m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip x -> Maybe a -> ExceptT x m a
    forall (m :: * -> *) x a. Monad m => x -> Maybe a -> ExceptT x m a
    fromMaybeExceptT

    -- | Similar to 'fromMaybeExceptT' except the 'Maybe' value is lifted in a
    -- 'Monad'.
    --
    -- >>> let identityNothing = Identity Nothing :: Identity (Maybe Bool)
    -- >>> fromMaybeMExceptT 5 identityNothing :: ExceptT Int Identity Bool
    -- ExceptT (Identity (Left 5))
    fromMaybeMExceptT :: Monad m => x -> m (Maybe a) -> ExceptT x m a
    fromMaybeMExceptT :: forall (m :: * -> *) x a.
    Monad m =>
    x -> m (Maybe a) -> ExceptT x m a
    fromMaybeMExceptT x
    handler m (Maybe a)
    action = do
      res <- m (Maybe a) -> ExceptT x m (Maybe a)
    forall (m :: * -> *) a. Monad m => m a -> ExceptT x m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m (Maybe a)
    action
      case res of
        Maybe a
    Nothing -> x -> ExceptT x m a
    forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
    throwE x
    handler
        Just a
    a -> a -> ExceptT x m a
    forall a. a -> ExceptT x m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure a
    a

    -- | Just like 'fromMaybeMExceptT' but with the arguments flipped.
    fromMaybeOrMExceptT :: Monad m => m (Maybe a) -> x -> ExceptT x m a
    fromMaybeOrMExceptT :: forall (m :: * -> *) a x.
    Monad m =>
    m (Maybe a) -> x -> ExceptT x m a
    fromMaybeOrMExceptT = (x -> m (Maybe a) -> ExceptT x m a)
    -> m (Maybe a) -> x -> ExceptT x m a
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip x -> m (Maybe a) -> ExceptT x m a
    forall (m :: * -> *) x a.
    Monad m =>
    x -> m (Maybe a) -> ExceptT x m a
    fromMaybeMExceptT

    -- | Similar to 'guard', but for 'ExceptT'.
    --
    -- If the 'Bool' is 'True', then do nothing.
    --
    -- >>> guardExceptT True "error occurred" :: ExceptT String Identity ()
    -- ExceptT (Identity (Right ()))
    --
    -- If the 'Bool' is 'False', then return the error case:
    --
    -- >>> guardExceptT False "error occurred" :: ExceptT String Identity ()
    -- ExceptT (Identity (Left "error occurred"))
    guardExceptT :: Monad m => Bool -> x -> ExceptT x m ()
    guardExceptT :: forall (m :: * -> *) x. Monad m => Bool -> x -> ExceptT x m ()
    guardExceptT Bool
    True x
    _ = () -> ExceptT x m ()
    forall a. a -> ExceptT x m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
    guardExceptT Bool
    False x
    handler = x -> ExceptT x m ()
    forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
    throwE x
    handler

    -- | Just like 'guardExceptT' (and similar to 'guardM'), except the boolean is
    -- lifted in a 'Monad'.
    --
    -- >>> guardMExceptT (Identity False) "error occurred" :: ExceptT String Identity ()
    -- ExceptT (Identity (Left "error occurred"))
    guardMExceptT :: Monad m => m Bool -> x -> ExceptT x m ()
    guardMExceptT :: forall (m :: * -> *) x. Monad m => m Bool -> x -> ExceptT x m ()
    guardMExceptT m Bool
    action x
    handler = do
      res <- m Bool -> ExceptT x m Bool
    forall (m :: * -> *) a. Monad m => m a -> ExceptT x m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m Bool
    action
      guardExceptT res handler

    -- $exampleExceptT
    --
    -- Functions like 'fromMaybeExceptT' and 'fromEitherExceptT' are convenient
    -- when paired with 'collapseErrExceptT'.  This section explains how
    -- you can use these functions together.
    --
    -- Imagine you're writing a function that pulls user names from a database,
    -- reads the first character of the name, and prints it to the console.
    -- The functions for reading names from a database, and for
    -- parsing the first character of the name could fail, so we will
    -- handle these errors by logging to the console.
    --
    -- Here's the function we will be using for pulling user names from
    -- the database.  If we pass @0@, it returns @\"SPJ\"@.  If we pass @1@,
    -- it returns an empty string.  Otherwise it returns 'Nothing':
    --
    -- >>> :{
    --   let getUserNameFromDb :: Int -> Maybe String
    --       getUserNameFromDb 0 = Just "SPJ"
    --       getUserNameFromDb 1 = Just ""
    --       getUserNameFromDb _ = Nothing
    -- :}
    --
    -- Here's the function we will be using for parsing the first character
    -- of a user name.  If the user name is an empty string, we return
    -- 'Left' with an error message.  Otherwise we return the first
    -- character of the user name:
    --
    -- >>> :{
    --   let parseFirstCharFromName :: String -> Either String Char
    --       parseFirstCharFromName [] = Left "user name is empty"
    --       parseFirstCharFromName (h:_) = Right h
    -- :}
    --
    -- Now let's write our function.  If you didn't have the combinators from above
    -- like 'fromEitherExceptT' and 'collapseErrExceptT', you might be tempted to
    -- write nested @case@ patterns:
    --
    -- >>> :{
    --   let nestedPrintFirstCharOfUserName :: Int -> IO ()
    --       nestedPrintFirstCharOfUserName i =
    --         -- Try to get the username for id i.
    --         case getUserNameFromDb i of
    --           -- If we couldn't get the user name from the database
    --           -- print an error to the console.
    --           Nothing -> putStrLn $ "ERROR: couldn't get user name for user " ++ show i
    --           Just name ->
    --             -- Try to parse the first character of the user name.
    --             case parseFirstCharFromName name of
    --               -- If we couldn't parse the first character of the user name,
    --               -- print an error to the console.
    --               Left err -> putStrLn $ "ERROR: " ++ err
    --               Right firstChar ->
    --                 -- Print the first character of the user name to the console.
    --                 putStrLn $
    --                   "Got first character of name for id " ++ show i ++ ": " ++ [firstChar]
    -- :}
    --
    -- Here's an example of using this function, including the error cases:
    --
    -- >>> nestedPrintFirstCharOfUserName 100
    -- ERROR: couldn't get user name for user 100
    -- >>> nestedPrintFirstCharOfUserName 1
    -- ERROR: user name is empty
    -- >>> nestedPrintFirstCharOfUserName 0
    -- Got first character of name for id 0: S
    --
    -- This works, and is understandable, but it gets unwieldy when there
    -- are even more parsing steps.  You can get very deeply nested cases.
    --
    -- In order to write this without deeply nested error handling, you need a
    -- short-circuiting 'Monad'.  Two popular examples are 'MaybeT' and 'ExceptT'.
    --
    -- Using 'collapseErrExceptT' (and 'ExcepT'), it is possible to write this
    -- function by short-circuiting on errors:
    --
    -- >>> :{
    --   let printFirstCharOfUserName :: Int -> IO ()
    --       printFirstCharOfUserName i =
    --         -- The argument to collapseErrExceptT is @ExceptT (IO ()) IO ()@.
    --         -- This can be thought of as an action that can short-circuit
    --         -- with @IO ()@ error-handling actions.
    --         --
    --         -- The error-handling actions below just log to the console.
    --         collapseErrExceptT $ do
    --           -- Get the user name from the db.
    --           -- If getUserNameFromDb returns Nothing, then this whole
    --           -- block will short circuit and collapseErrExceptT will
    --           -- run our error handler.
    --           --
    --           -- Note that for the type of the error handler to work
    --           -- correctly with @collapseErrExceptT@, the error
    --           -- handler has to return @IO ()@.
    --           name <-
    --             fromMaybeOrExceptT (getUserNameFromDb i) $
    --               putStrLn $ "ERROR: couldn't get user name for user " ++ show i
    --           -- Parse out the first character from the user name.
    --           -- If parseFirstCharFromName returns Left, then this whole
    --           -- block will short circuit and collapseErrExceptT will
    --           -- run our error handler.
    --           firstChar <-
    --             fromEitherOrExceptT (parseFirstCharFromName name) $ \err ->
    --               putStrLn $ "ERROR: " ++ err
    --           -- Print the first character of the name.
    --           -- This needs to be 'lift'ed because this whole block is
    --           -- actually @ExceptT (IO ()) IO ()@.
    --           lift $
    --             putStrLn $
    --               "Got first character of name for id " ++ show i ++ ": " ++ [firstChar]
    -- :}
    --
    -- The main good point here is that using the short-circuiting functionality of
    -- 'ExceptT', we can write everything without nesting.
    --
    -- Here's a few examples of calling @printFirstCharOfUserName@.
    --
    -- Here we pass a user id that doesn't exist, so @getUserNameFromDb@ will
    -- return 'Nothing'.  This causes the function to short-circuit and the
    -- first error handler to be called.
    --
    -- >>> printFirstCharOfUserName 100
    -- ERROR: couldn't get user name for user 100
    --
    -- Here we pass a user id that does exist, but the user name for this user id
    -- is empty.  This causes the function to short-circuit and the
    -- second error handler to be called.
    --
    -- >>> printFirstCharOfUserName 1
    -- ERROR: user name is empty
    --
    -- This time the function succeeds:
    --
    -- >>> printFirstCharOfUserName 0
    -- Got first character of name for id 0: S
    --
    -- In real code, the functions @getUserNameFromDb@ and @parseFirstCharFromName@
    -- will have monadic return values.  In that case, you can use
    -- 'fromMaybeOrMExceptT' and 'fromEitherOrMExceptT'.