{-# 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 = Dict (Functor (ExceptT e m))
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 = Dict (Monad (ExceptT e m))
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 = Dict (MonadIO (ExceptT e m))
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 = Dict (MonadFail (ExceptT e m))
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 = Dict (MonadFix (ExceptT e m))
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 = Dict (MonadPlus (ExceptT e m))
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 m (Either e a) -> Result (Exc m) (Either e a)
forall a. m a -> Result (Exc m) a
forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner m (Either e a)
meea of
            SuccessResult (Right a
a) -> a -> Result (Either e (Exc m)) a
forall e a. a -> Result e a
SuccessResult a
a
            SuccessResult (Left e
e) -> Exc (ExceptT e m) -> Result (Exc (ExceptT e m)) a
forall e a. e -> Result e a
FailureResult (Exc (ExceptT e m) -> Result (Exc (ExceptT e m)) a)
-> Exc (ExceptT e m) -> Result (Exc (ExceptT e m)) a
forall a b. (a -> b) -> a -> b
$ e -> Either e (Exc m)
forall a b. a -> Either a b
Left e
e
            FailureResult Exc m
e -> Exc (ExceptT e m) -> Result (Exc (ExceptT e m)) a
forall e a. e -> Result e a
FailureResult (Exc (ExceptT e m) -> Result (Exc (ExceptT e m)) a)
-> Exc (ExceptT e m) -> Result (Exc (ExceptT e m)) a
forall a b. (a -> b) -> a -> b
$ Exc m -> Either e (Exc m)
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 = Dict (MonadInner (ExceptT e m))
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 = Dict (Coercible (ExceptT e m1) (ExceptT e m2))
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) = m (Either e a) -> ExceptT e m a
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ Either e a -> m (Either e a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Either e a -> m (Either e a)) -> Either e a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ e -> Either e a
forall a b. a -> Either a b
Left e
e
    throwExc (Right Exc m
e) = m (Either e a) -> ExceptT e m a
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ Exc m -> m (Either e a)
forall a. Exc m -> m a
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 =
        m (Either e a) -> ExceptT e m a
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ do
            Result (Exc m) (Either e a)
ea <- m (Either e a) -> m (Result (Exc m) (Either e a))
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 -> ExceptT e m a -> m (Either e a)
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m a -> m (Either e a))
-> ExceptT e m a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ Exc (ExceptT e m) -> ExceptT e m a
handler (Exc (ExceptT e m) -> ExceptT e m a)
-> Exc (ExceptT e m) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ Exc m -> Either e (Exc m)
forall a b. b -> Either a b
Right Exc m
e
                SuccessResult (Left e
e) -> ExceptT e m a -> m (Either e a)
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m a -> m (Either e a))
-> ExceptT e m a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ Exc (ExceptT e m) -> ExceptT e m a
handler (Exc (ExceptT e m) -> ExceptT e m a)
-> Exc (ExceptT e m) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ e -> Either e (Exc m)
forall a b. a -> Either a b
Left e
e
                SuccessResult (Right a
a) -> Either e a -> m (Either e a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Either e a -> m (Either e a)) -> Either e a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ a -> Either e a
forall a. a -> Either e a
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 = Dict (MonadException (ExceptT e m))
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) = m (Either e a) -> ExceptT e m a
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ Either e a -> m (Either e a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Either e a -> m (Either e a)) -> Either e a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ e -> Either e a
forall a b. a -> Either a b
Left e
e
    throw (Right ex
e) = m (Either e a) -> ExceptT e m a
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ ex -> m (Either e a)
forall a. ex -> m a
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 =
        m (Either e a) -> ExceptT e m a
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e a) -> ExceptT e m a)
-> m (Either e a) -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ do
            Result ex (Either e a)
ea <- m (Either e a) -> m (Result ex (Either e a))
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 -> ExceptT e m a -> m (Either e a)
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m a -> m (Either e a))
-> ExceptT e m a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ Either e ex -> ExceptT e m a
handler (Either e ex -> ExceptT e m a) -> Either e ex -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ ex -> Either e ex
forall a b. b -> Either a b
Right ex
e
                SuccessResult (Left e
e) -> ExceptT e m a -> m (Either e a)
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m a -> m (Either e a))
-> ExceptT e m a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ Either e ex -> ExceptT e m a
handler (Either e ex -> ExceptT e m a) -> Either e ex -> ExceptT e m a
forall a b. (a -> b) -> a -> b
$ e -> Either e ex
forall a b. a -> Either a b
Left e
e
                SuccessResult (Right a
a) -> Either e a -> m (Either e a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Either e a -> m (Either e a)) -> Either e a -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ a -> Either e a
forall a. a -> Either e a
forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a

transExcept ::
       forall t m e a. (MonadTransTunnel t, Monad m)
    => t (ExceptT e m) a
    -> t m (Either e a)
transExcept :: forall (t :: TransKind) (m :: Type -> Type) e a.
(MonadTransTunnel t, Monad m) =>
t (ExceptT e m) a -> t m (Either e a)
transExcept t (ExceptT e m) a
tema = ((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  t m1 a -> m1 (Tunnel t a))
 -> m (Tunnel t (Either e a)))
-> t m (Either e a)
forall (m :: Type -> Type) r.
Monad m =>
((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  t m1 a -> m1 (Tunnel t a))
 -> m (Tunnel t r))
-> t m r
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 (m1 :: Type -> Type) a.
   Monad m1 =>
   t m1 a -> m1 (Tunnel t a))
  -> m (Tunnel t (Either e a)))
 -> t m (Either e a))
-> ((forall (m1 :: Type -> Type) a.
     Monad m1 =>
     t m1 a -> m1 (Tunnel t a))
    -> m (Tunnel t (Either e a)))
-> t m (Either e a)
forall a b. (a -> b) -> a -> b
$ \forall (m1 :: Type -> Type) a.
Monad m1 =>
t m1 a -> m1 (Tunnel t a)
unlift -> (Either e (Tunnel t a) -> Tunnel t (Either e a))
-> m (Either e (Tunnel t a)) -> m (Tunnel t (Either e a))
forall a b. (a -> b) -> m a -> m b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Either e (Tunnel t a) -> Tunnel t (Either e a)
forall (m :: Type -> Type) (f :: Type -> Type) a.
(MonadInner m, Applicative f) =>
m (f a) -> f (m a)
commuteInner (m (Either e (Tunnel t a)) -> m (Tunnel t (Either e a)))
-> m (Either e (Tunnel t a)) -> m (Tunnel t (Either e a))
forall a b. (a -> b) -> a -> b
$ ExceptT e m (Tunnel t a) -> m (Either e (Tunnel t a))
forall e (m :: Type -> Type) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT e m (Tunnel t a) -> m (Either e (Tunnel t a)))
-> ExceptT e m (Tunnel t a) -> m (Either e (Tunnel t a))
forall a b. (a -> b) -> a -> b
$ t (ExceptT e m) a -> ExceptT e m (Tunnel t a)
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 = (m1 --> m2) -> ExceptT e m1 --> ExceptT e m2
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 = m (Either e r) -> ExceptT e m r
forall e (m :: Type -> Type) a. m (Either e a) -> ExceptT e m a
ExceptT (m (Either e r) -> ExceptT e m r)
-> m (Either e r) -> ExceptT e m r
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 (m1 :: Type -> Type) a.
  Monad m1 =>
  ExceptT e m1 a -> m1 (Tunnel (ExceptT e) a))
 -> m (Tunnel (ExceptT e) r))
-> (forall (m1 :: Type -> Type) a.
    Monad m1 =>
    ExceptT e m1 a -> m1 (Tunnel (ExceptT e) a))
-> m (Tunnel (ExceptT e) r)
forall a b. (a -> b) -> a -> b
$ \(ExceptT m1 (Either e a)
ma) -> m1 (Either e a)
m1 (Tunnel (ExceptT e) a)
ma