{-# OPTIONS -fno-warn-orphans #-}

module Control.Monad.Ology.Specific.ExceptT
    ( module Control.Monad.Trans.Except
    , module Control.Monad.Ology.Specific.ExceptT
    ) where

import Control.Monad.Ology.General
import Control.Monad.Ology.Specific.Result
import Control.Monad.Trans.Except hiding (liftCallCC, liftListen, liftPass)
import Import

instance TransConstraint Functor (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type).
Functor m =>
Dict (Functor (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance TransConstraint Monad (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type). Monad m => Dict (Monad (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance TransConstraint MonadIO (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadIO m =>
Dict (MonadIO (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance TransConstraint MonadFail (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadFail m =>
Dict (MonadFail (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance TransConstraint MonadFix (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadFix m =>
Dict (MonadFix (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance Monoid e => TransConstraint MonadPlus (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadPlus m =>
Dict (MonadPlus (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance MonadInner m => MonadInner (ExceptT e m) where
    retrieveInner :: forall a. ExceptT e m a -> Result (Exc (ExceptT e m)) a
retrieveInner (ExceptT m (Either e a)
meea) =
        case forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner m (Either e a)
meea of
            SuccessResult (Right a
a) -> forall e a. a -> Result e a
SuccessResult a
a
            SuccessResult (Left e
e) -> forall e a. e -> Result e a
FailureResult forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left e
e
            FailureResult Exc m
e -> forall e a. e -> Result e a
FailureResult forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Exc m
e

instance TransConstraint MonadInner (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadInner m =>
Dict (MonadInner (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance MonadTransCoerce (ExceptT e) where
    transCoerce :: forall (m1 :: Type -> Type) (m2 :: Type -> Type).
Coercible m1 m2 =>
Dict (Coercible (ExceptT e m1) (ExceptT e m2))
transCoerce = forall (a :: Constraint). a => Dict a
Dict

instance MonadException m => MonadException (ExceptT e m) where
    type Exc (ExceptT e m) = Either e (Exc m)
    throwExc :: forall a. Exc (ExceptT e m) -> ExceptT e m a
throwExc (Left e
e) = forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left e
e
    throwExc (Right Exc m
e) = forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. MonadException m => Exc m -> m a
throwExc Exc m
e
    catchExc :: forall a.
ExceptT e m a
-> (Exc (ExceptT e m) -> ExceptT e m a) -> ExceptT e m a
catchExc (ExceptT m (Either e a)
mea) Exc (ExceptT e m) -> ExceptT e m a
handler =
        forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ do
            Result (Exc m) (Either e a)
ea <- forall (m :: Type -> Type) a.
MonadException m =>
m a -> m (Result (Exc m) a)
tryExc m (Either e a)
mea
            case Result (Exc m) (Either e a)
ea of
                FailureResult Exc m
e -> forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT forall a b. (a -> b) -> a -> b
$ Exc (ExceptT e m) -> ExceptT e m a
handler forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Exc m
e
                SuccessResult (Left e
e) -> forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT forall a b. (a -> b) -> a -> b
$ Exc (ExceptT e m) -> ExceptT e m a
handler forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left e
e
                SuccessResult (Right a
a) -> forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a

instance TransConstraint MonadException (ExceptT e) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadException m =>
Dict (MonadException (ExceptT e m))
hasTransConstraint = forall (a :: Constraint). a => Dict a
Dict

instance MonadThrow ex m => MonadThrow (Either e ex) (ExceptT e m) where
    throw :: forall a. Either e ex -> ExceptT e m a
throw (Left e
e) = forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left e
e
    throw (Right ex
e) = forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ forall e (m :: Type -> Type) a. MonadThrow e m => e -> m a
throw ex
e

instance MonadCatch ex m => MonadCatch (Either e ex) (ExceptT e m) where
    catch :: forall a.
ExceptT e m a -> (Either e ex -> ExceptT e m a) -> ExceptT e m a
catch (ExceptT m (Either e a)
mea) Either e ex -> ExceptT e m a
handler =
        forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ do
            Result ex (Either e a)
ea <- forall (m :: Type -> Type) e a.
MonadCatch e m =>
m a -> m (Result e a)
try m (Either e a)
mea
            case Result ex (Either e a)
ea of
                FailureResult ex
e -> forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT forall a b. (a -> b) -> a -> b
$ Either e ex -> ExceptT e m a
handler forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right ex
e
                SuccessResult (Left e
e) -> forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT forall a b. (a -> b) -> a -> b
$ Either e ex -> ExceptT e m a
handler forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left e
e
                SuccessResult (Right a
a) -> forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a

transExcept ::
       forall t m e a. (MonadTransTunnel t, Applicative (Tunnel t), Monad m)
    => t (ExceptT e m) a
    -> t m (Either e a)
transExcept :: forall (t :: TransKind) (m :: Type -> Type) e a.
(MonadTransTunnel t, Applicative (Tunnel t), Monad m) =>
t (ExceptT e m) a -> t m (Either e a)
transExcept t (ExceptT e m) a
tema = forall (t :: TransKind) (m :: Type -> Type) r.
(MonadTransTunnel t, Monad m) =>
((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  t m1 a -> m1 (Tunnel t a))
 -> m (Tunnel t r))
-> t m r
tunnel forall a b. (a -> b) -> a -> b
$ \forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift -> forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (m :: Type -> Type) (f :: Type -> Type) a.
(MonadInner m, Applicative f) =>
m (f a) -> f (m a)
commuteInner forall a b. (a -> b) -> a -> b
$ forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT forall a b. (a -> b) -> a -> b
$ forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift t (ExceptT e m) a
tema

instance MonadTransHoist (ExceptT e) where
    hoist :: forall (m1 :: Type -> Type) (m2 :: Type -> Type).
(Monad m1, Monad m2) =>
(m1 --> m2) -> ExceptT e m1 --> ExceptT e m2
hoist = forall (t :: TransKind) (m1 :: Type -> Type) (m2 :: Type -> Type).
(MonadTransTunnel t, Monad m1, Monad m2) =>
(m1 --> m2) -> t m1 --> t m2
tunnelHoist

instance MonadTransTunnel (ExceptT e) where
    type Tunnel (ExceptT e) = Either e
    tunnel :: forall (m :: Type -> Type) r.
Monad m =>
((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  ExceptT e m1 a -> m1 (Tunnel (ExceptT e) a))
 -> m (Tunnel (ExceptT e) r))
-> ExceptT e m r
tunnel (forall (m1 :: Type -> Type) a.
 Monad m1 =>
 ExceptT e m1 a -> m1 (Tunnel (ExceptT e) a))
-> m (Tunnel (ExceptT e) r)
call = forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT forall a b. (a -> b) -> a -> b
$ (forall (m1 :: Type -> Type) a.
 Monad m1 =>
 ExceptT e m1 a -> m1 (Tunnel (ExceptT e) a))
-> m (Tunnel (ExceptT e) r)
call forall a b. (a -> b) -> a -> b
$ \(ExceptT m1 (Either e a)
ma) -> m1 (Either e a)
ma