module Control.Monad.Ology.Specific.ComposeInner where

import Control.Monad.Ology.General.Exception.Class
import Control.Monad.Ology.General.Extract
import Control.Monad.Ology.General.Function
import Control.Monad.Ology.General.IO
import Control.Monad.Ology.General.Identity
import Control.Monad.Ology.General.Inner
import Control.Monad.Ology.General.Outer
import Control.Monad.Ology.General.Trans.Constraint
import Control.Monad.Ology.General.Trans.Hoist
import Control.Monad.Ology.General.Trans.Trans
import Control.Monad.Ology.Specific.Result
import Import

type ComposeInner :: (Type -> Type) -> (Type -> Type) -> Type -> Type
newtype ComposeInner inner outer a = MkComposeInner
    { forall (inner :: Type -> Type) (outer :: Type -> Type) a.
ComposeInner inner outer a -> outer (inner a)
unComposeInner :: outer (inner a)
    }

instance forall inner outer. (Foldable inner, Foldable outer, Functor outer) => Foldable (ComposeInner inner outer) where
    foldMap :: forall m a. Monoid m => (a -> m) -> ComposeInner inner outer a -> m
foldMap a -> m
am (MkComposeInner outer (inner a)
oia) = (m -> m) -> outer m -> m
forall m a. Monoid m => (a -> m) -> outer a -> m
forall (t :: Type -> Type) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap m -> m
forall a. a -> a
forall {k} (cat :: k -> k -> Type) (a :: k).
Category cat =>
cat a a
id (outer m -> m) -> outer m -> m
forall a b. (a -> b) -> a -> b
$ (inner a -> m) -> outer (inner a) -> outer m
forall a b. (a -> b) -> outer a -> outer b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> m) -> inner a -> m
forall m a. Monoid m => (a -> m) -> inner a -> m
forall (t :: Type -> Type) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
am) outer (inner a)
oia

instance forall inner outer. (Traversable inner, Traversable outer) => Traversable (ComposeInner inner outer) where
    traverse :: forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b)
-> ComposeInner inner outer a -> f (ComposeInner inner outer b)
traverse a -> f b
afb (MkComposeInner outer (inner a)
oia) = (outer (inner b) -> ComposeInner inner outer b)
-> f (outer (inner b)) -> f (ComposeInner inner outer b)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap outer (inner b) -> ComposeInner inner outer b
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (f (outer (inner b)) -> f (ComposeInner inner outer b))
-> f (outer (inner b)) -> f (ComposeInner inner outer b)
forall a b. (a -> b) -> a -> b
$ (inner a -> f (inner b)) -> outer (inner a) -> f (outer (inner b))
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> outer a -> f (outer b)
traverse ((a -> f b) -> inner a -> f (inner b)
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: Type -> Type) a b.
Applicative f =>
(a -> f b) -> inner a -> f (inner b)
traverse a -> f b
afb) outer (inner a)
oia

instance forall inner. Traversable inner => TransConstraint Traversable (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
Traversable m =>
Dict (Traversable (ComposeInner inner m))
hasTransConstraint = Dict (Traversable (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner outer. (Functor inner, Functor outer) => Functor (ComposeInner inner outer) where
    fmap :: forall a b.
(a -> b)
-> ComposeInner inner outer a -> ComposeInner inner outer b
fmap a -> b
ab (MkComposeInner outer (inner a)
oia) = outer (inner b) -> ComposeInner inner outer b
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner b) -> ComposeInner inner outer b)
-> outer (inner b) -> ComposeInner inner outer b
forall a b. (a -> b) -> a -> b
$ (inner a -> inner b) -> outer (inner a) -> outer (inner b)
forall a b. (a -> b) -> outer a -> outer b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> inner a -> inner b
forall a b. (a -> b) -> inner a -> inner b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
ab) outer (inner a)
oia

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

instance forall inner outer. (MonadInner inner, Monad outer) => Applicative (ComposeInner inner outer) where
    pure :: forall a. a -> ComposeInner inner outer a
pure a
a = outer (inner a) -> ComposeInner inner outer a
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner a) -> ComposeInner inner outer a)
-> outer (inner a) -> ComposeInner inner outer a
forall a b. (a -> b) -> a -> b
$ inner a -> outer (inner a)
forall a. a -> outer a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (inner a -> outer (inner a)) -> inner a -> outer (inner a)
forall a b. (a -> b) -> a -> b
$ a -> inner a
forall a. a -> inner a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
a
    -- cannot use obvious definition for <*>, because that would incorrectly execute the outer part of ma even if mab fails
    ComposeInner inner outer (a -> b)
mab <*> :: forall a b.
ComposeInner inner outer (a -> b)
-> ComposeInner inner outer a -> ComposeInner inner outer b
<*> ComposeInner inner outer a
ma = do
        a -> b
ab <- ComposeInner inner outer (a -> b)
mab
        a
a <- ComposeInner inner outer a
ma
        b -> ComposeInner inner outer b
forall a. a -> ComposeInner inner outer a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (b -> ComposeInner inner outer b)
-> b -> ComposeInner inner outer b
forall a b. (a -> b) -> a -> b
$ a -> b
ab a
a

instance forall inner outer. (MonadInner inner, Monad outer, Alternative inner) =>
             Alternative (ComposeInner inner outer) where
    empty :: forall a. ComposeInner inner outer a
empty = outer (inner a) -> ComposeInner inner outer a
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner a) -> ComposeInner inner outer a)
-> outer (inner a) -> ComposeInner inner outer a
forall a b. (a -> b) -> a -> b
$ inner a -> outer (inner a)
forall a. a -> outer a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure inner a
forall a. inner a
forall (f :: Type -> Type) a. Alternative f => f a
empty
    -- cannot use obvious definition for <|> for similar reasons as in <*>
    (MkComposeInner outer (inner a)
oia) <|> :: forall a.
ComposeInner inner outer a
-> ComposeInner inner outer a -> ComposeInner inner outer a
<|> ComposeInner inner outer a
cb = do
        Maybe a
ma <-
            outer (inner (Maybe a)) -> ComposeInner inner outer (Maybe a)
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner (Maybe a)) -> ComposeInner inner outer (Maybe a))
-> outer (inner (Maybe a)) -> ComposeInner inner outer (Maybe a)
forall a b. (a -> b) -> a -> b
$ do
                inner a
ia <- outer (inner a)
oia
                inner (Maybe a) -> outer (inner (Maybe a))
forall a. a -> outer a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (inner (Maybe a) -> outer (inner (Maybe a)))
-> inner (Maybe a) -> outer (inner (Maybe a))
forall a b. (a -> b) -> a -> b
$ (a -> Maybe a) -> inner a -> inner (Maybe a)
forall a b. (a -> b) -> inner a -> inner b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Maybe a
forall a. a -> Maybe a
Just inner a
ia inner (Maybe a) -> inner (Maybe a) -> inner (Maybe a)
forall a. inner a -> inner a -> inner a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> Maybe a -> inner (Maybe a)
forall a. a -> inner a
forall (m :: Type -> Type) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
        case Maybe a
ma of
            Just a
a -> a -> ComposeInner inner outer a
forall a. a -> ComposeInner inner outer a
forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a
            Maybe a
Nothing -> ComposeInner inner outer a
cb

instance forall inner outer. (MonadInner inner, Monad outer) => Monad (ComposeInner inner outer) where
    return :: forall a. a -> ComposeInner inner outer a
return = a -> ComposeInner inner outer a
forall a. a -> ComposeInner inner outer a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure
    (MkComposeInner outer (inner a)
oia) >>= :: forall a b.
ComposeInner inner outer a
-> (a -> ComposeInner inner outer b) -> ComposeInner inner outer b
>>= a -> ComposeInner inner outer b
p =
        outer (inner b) -> ComposeInner inner outer b
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner b) -> ComposeInner inner outer b)
-> outer (inner b) -> ComposeInner inner outer b
forall a b. (a -> b) -> a -> b
$ do
            inner a
ia <- outer (inner a)
oia
            case inner a -> Result (Exc inner) a
forall a. inner a -> Result (Exc inner) a
forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner inner a
ia of
                SuccessResult a
a -> do
                    inner b
ib <- ComposeInner inner outer b -> outer (inner b)
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
ComposeInner inner outer a -> outer (inner a)
unComposeInner (ComposeInner inner outer b -> outer (inner b))
-> ComposeInner inner outer b -> outer (inner b)
forall a b. (a -> b) -> a -> b
$ a -> ComposeInner inner outer b
p a
a
                    inner b -> outer (inner b)
forall a. a -> outer a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (inner b -> outer (inner b)) -> inner b -> outer (inner b)
forall a b. (a -> b) -> a -> b
$ inner a
ia inner a -> inner b -> inner b
forall a b. inner a -> inner b -> inner b
forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
>> inner b
ib
                FailureResult Exc inner
e -> inner b -> outer (inner b)
forall a. a -> outer a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (inner b -> outer (inner b)) -> inner b -> outer (inner b)
forall a b. (a -> b) -> a -> b
$ Exc inner -> inner b
forall a. Exc inner -> inner a
forall (m :: Type -> Type) a. MonadException m => Exc m -> m a
throwExc Exc inner
e

instance forall inner. MonadInner inner => TransConstraint Monad (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
Monad m =>
Dict (Monad (ComposeInner inner m))
hasTransConstraint = Dict (Monad (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner outer. (MonadInner inner, MonadFail outer) => MonadFail (ComposeInner inner outer) where
    fail :: forall a. String -> ComposeInner inner outer a
fail String
s = outer a -> ComposeInner inner outer a
forall (m :: Type -> Type) a.
Monad m =>
m a -> ComposeInner inner m a
forall (t :: TransKind) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (outer a -> ComposeInner inner outer a)
-> outer a -> ComposeInner inner outer a
forall a b. (a -> b) -> a -> b
$ String -> outer a
forall a. String -> outer a
forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail String
s

instance forall inner. MonadInner inner => TransConstraint MonadFail (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadFail m =>
Dict (MonadFail (ComposeInner inner m))
hasTransConstraint = Dict (MonadFail (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner outer. (MonadInner inner, MonadInner outer) => MonadInner (ComposeInner inner outer) where
    retrieveInner :: forall a.
ComposeInner inner outer a
-> Result (Exc (ComposeInner inner outer)) a
retrieveInner (MkComposeInner outer (inner a)
oia) =
        case outer (inner a) -> Result (Exc outer) (inner a)
forall a. outer a -> Result (Exc outer) a
forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner outer (inner a)
oia of
            SuccessResult inner a
ia ->
                case inner a -> Result (Exc inner) a
forall a. inner a -> Result (Exc inner) a
forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner inner a
ia of
                    SuccessResult a
a -> a -> Result (Either (Exc inner) (Exc outer)) a
forall e a. a -> Result e a
SuccessResult a
a
                    FailureResult Exc inner
e -> Exc (ComposeInner inner outer)
-> Result (Exc (ComposeInner inner outer)) a
forall e a. e -> Result e a
FailureResult (Exc (ComposeInner inner outer)
 -> Result (Exc (ComposeInner inner outer)) a)
-> Exc (ComposeInner inner outer)
-> Result (Exc (ComposeInner inner outer)) a
forall a b. (a -> b) -> a -> b
$ Exc inner -> Either (Exc inner) (Exc outer)
forall a b. a -> Either a b
Left Exc inner
e
            FailureResult Exc outer
e -> Exc (ComposeInner inner outer)
-> Result (Exc (ComposeInner inner outer)) a
forall e a. e -> Result e a
FailureResult (Exc (ComposeInner inner outer)
 -> Result (Exc (ComposeInner inner outer)) a)
-> Exc (ComposeInner inner outer)
-> Result (Exc (ComposeInner inner outer)) a
forall a b. (a -> b) -> a -> b
$ Exc outer -> Either (Exc inner) (Exc outer)
forall a b. b -> Either a b
Right Exc outer
e

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

instance forall inner outer. (MonadInner inner, MonadOuter inner, MonadOuter outer) =>
             MonadOuter (ComposeInner inner outer) where
    getExtract :: ComposeInner inner outer (WExtract (ComposeInner inner outer))
getExtract =
        outer (inner (WExtract (ComposeInner inner outer)))
-> ComposeInner inner outer (WExtract (ComposeInner inner outer))
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner (WExtract (ComposeInner inner outer)))
 -> ComposeInner inner outer (WExtract (ComposeInner inner outer)))
-> outer (inner (WExtract (ComposeInner inner outer)))
-> ComposeInner inner outer (WExtract (ComposeInner inner outer))
forall a b. (a -> b) -> a -> b
$ do
            MkWExtract Extract outer
oaa <- outer (WExtract outer)
forall (m :: Type -> Type). MonadOuter m => m (WExtract m)
getExtract
            inner (WExtract (ComposeInner inner outer))
-> outer (inner (WExtract (ComposeInner inner outer)))
forall a. a -> outer a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (inner (WExtract (ComposeInner inner outer))
 -> outer (inner (WExtract (ComposeInner inner outer))))
-> inner (WExtract (ComposeInner inner outer))
-> outer (inner (WExtract (ComposeInner inner outer)))
forall a b. (a -> b) -> a -> b
$ do
                MkWExtract Extract inner
iaa <- inner (WExtract inner)
forall (m :: Type -> Type). MonadOuter m => m (WExtract m)
getExtract
                WExtract (ComposeInner inner outer)
-> inner (WExtract (ComposeInner inner outer))
forall a. a -> inner a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (WExtract (ComposeInner inner outer)
 -> inner (WExtract (ComposeInner inner outer)))
-> WExtract (ComposeInner inner outer)
-> inner (WExtract (ComposeInner inner outer))
forall a b. (a -> b) -> a -> b
$ Extract (ComposeInner inner outer)
-> WExtract (ComposeInner inner outer)
forall (m :: Type -> Type). Extract m -> WExtract m
MkWExtract (Extract (ComposeInner inner outer)
 -> WExtract (ComposeInner inner outer))
-> Extract (ComposeInner inner outer)
-> WExtract (ComposeInner inner outer)
forall a b. (a -> b) -> a -> b
$ \(MkComposeInner outer (inner a)
oia) -> inner a -> a
Extract inner
iaa (inner a -> a) -> inner a -> a
forall a b. (a -> b) -> a -> b
$ outer (inner a) -> inner a
Extract outer
oaa outer (inner a)
oia

instance forall inner. (MonadInner inner, MonadOuter inner) => TransConstraint MonadOuter (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadOuter m =>
Dict (MonadOuter (ComposeInner inner m))
hasTransConstraint = Dict (MonadOuter (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner outer. (MonadInner inner, MonadFix outer) => MonadFix (ComposeInner inner outer) where
    mfix :: forall a.
(a -> ComposeInner inner outer a) -> ComposeInner inner outer a
mfix a -> ComposeInner inner outer a
ama =
        outer (inner a) -> ComposeInner inner outer a
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner a) -> ComposeInner inner outer a)
-> outer (inner a) -> ComposeInner inner outer a
forall a b. (a -> b) -> a -> b
$
        (inner a -> outer (inner a)) -> outer (inner a)
forall a. (a -> outer a) -> outer a
forall (m :: Type -> Type) a. MonadFix m => (a -> m a) -> m a
mfix ((inner a -> outer (inner a)) -> outer (inner a))
-> (inner a -> outer (inner a)) -> outer (inner a)
forall a b. (a -> b) -> a -> b
$ \inner a
ia ->
            ComposeInner inner outer a -> outer (inner a)
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
ComposeInner inner outer a -> outer (inner a)
unComposeInner (ComposeInner inner outer a -> outer (inner a))
-> ComposeInner inner outer a -> outer (inner a)
forall a b. (a -> b) -> a -> b
$
            a -> ComposeInner inner outer a
ama (a -> ComposeInner inner outer a)
-> a -> ComposeInner inner outer a
forall a b. (a -> b) -> a -> b
$
            case inner a -> Result (Exc inner) a
forall a. inner a -> Result (Exc inner) a
forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner inner a
ia of
                SuccessResult a
a -> a
a
                FailureResult Exc inner
_ -> String -> a
forall a. HasCallStack => String -> a
error String
"bad ComposeInner mfix"

instance forall inner. MonadInner inner => TransConstraint MonadFix (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadFix m =>
Dict (MonadFix (ComposeInner inner m))
hasTransConstraint = Dict (MonadFix (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner outer. (MonadInner inner, Monad outer, Alternative inner) => MonadPlus (ComposeInner inner outer)

instance forall inner outer. (MonadExtract inner, MonadExtract outer) => MonadExtract (ComposeInner inner outer) where
    mToValue :: Extract (ComposeInner inner outer)
mToValue (MkComposeInner outer (inner a)
oia) = inner a -> a
Extract inner
forall (m :: Type -> Type). MonadExtract m => Extract m
mToValue (inner a -> a) -> inner a -> a
forall a b. (a -> b) -> a -> b
$ outer (inner a) -> inner a
Extract outer
forall (m :: Type -> Type). MonadExtract m => Extract m
mToValue outer (inner a)
oia

instance forall inner. MonadExtract inner => TransConstraint MonadExtract (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadExtract m =>
Dict (MonadExtract (ComposeInner inner m))
hasTransConstraint = Dict (MonadExtract (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner outer. (MonadIdentity inner, MonadIdentity outer) => MonadIdentity (ComposeInner inner outer)

instance forall inner. MonadIdentity inner => TransConstraint MonadIdentity (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadIdentity m =>
Dict (MonadIdentity (ComposeInner inner m))
hasTransConstraint = Dict (MonadIdentity (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner outer. (MonadInner inner, MonadIO outer) => MonadIO (ComposeInner inner outer) where
    liftIO :: forall a. IO a -> ComposeInner inner outer a
liftIO IO a
ioa = outer a -> ComposeInner inner outer a
forall (m :: Type -> Type) a.
Monad m =>
m a -> ComposeInner inner m a
forall (t :: TransKind) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (outer a -> ComposeInner inner outer a)
-> outer a -> ComposeInner inner outer a
forall a b. (a -> b) -> a -> b
$ IO a -> outer a
forall a. IO a -> outer a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO IO a
ioa

instance forall inner. MonadInner inner => TransConstraint MonadIO (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadIO m =>
Dict (MonadIO (ComposeInner inner m))
hasTransConstraint = Dict (MonadIO (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

liftInner ::
       forall inner outer. Applicative outer
    => inner --> ComposeInner inner outer
liftInner :: forall (inner :: Type -> Type) (outer :: Type -> Type).
Applicative outer =>
inner --> ComposeInner inner outer
liftInner inner a
na = outer (inner a) -> ComposeInner inner outer a
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (outer (inner a) -> ComposeInner inner outer a)
-> outer (inner a) -> ComposeInner inner outer a
forall a b. (a -> b) -> a -> b
$ inner a -> outer (inner a)
forall a. a -> outer a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure inner a
na

instance forall inner m. (MonadInner inner, MonadException inner, MonadException m) =>
             MonadException (ComposeInner inner m) where
    type Exc (ComposeInner inner m) = Either (Exc inner) (Exc m)
    throwExc :: forall a. Exc (ComposeInner inner m) -> ComposeInner inner m a
throwExc (Left Exc inner
e) = inner a -> ComposeInner inner m a
inner --> ComposeInner inner m
forall (inner :: Type -> Type) (outer :: Type -> Type).
Applicative outer =>
inner --> ComposeInner inner outer
liftInner (inner a -> ComposeInner inner m a)
-> inner a -> ComposeInner inner m a
forall a b. (a -> b) -> a -> b
$ Exc inner -> inner a
forall a. Exc inner -> inner a
forall (m :: Type -> Type) a. MonadException m => Exc m -> m a
throwExc Exc inner
e
    throwExc (Right Exc m
e) = m a -> ComposeInner inner m a
forall (m :: Type -> Type) a.
Monad m =>
m a -> ComposeInner inner m a
forall (t :: TransKind) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> ComposeInner inner m a) -> m a -> ComposeInner inner m a
forall a b. (a -> b) -> a -> b
$ Exc m -> m 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.
ComposeInner inner m a
-> (Exc (ComposeInner inner m) -> ComposeInner inner m a)
-> ComposeInner inner m a
catchExc (MkComposeInner m (inner a)
mia) Exc (ComposeInner inner m) -> ComposeInner inner m a
handler =
        m (inner a) -> ComposeInner inner m a
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (m (inner a) -> ComposeInner inner m a)
-> m (inner a) -> ComposeInner inner m a
forall a b. (a -> b) -> a -> b
$ do
            Result (Exc m) (inner a)
ira <- m (inner a) -> m (Result (Exc m) (inner a))
forall (m :: Type -> Type) a.
MonadException m =>
m a -> m (Result (Exc m) a)
tryExc m (inner a)
mia
            case (inner a -> Result (Exc inner) a)
-> Result (Exc m) (inner a)
-> Result (Exc m) (Result (Exc inner) a)
forall a b. (a -> b) -> Result (Exc m) a -> Result (Exc m) b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap inner a -> Result (Exc inner) a
forall a. inner a -> Result (Exc inner) a
forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner Result (Exc m) (inner a)
ira of
                FailureResult Exc m
e -> ComposeInner inner m a -> m (inner a)
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
ComposeInner inner outer a -> outer (inner a)
unComposeInner (ComposeInner inner m a -> m (inner a))
-> ComposeInner inner m a -> m (inner a)
forall a b. (a -> b) -> a -> b
$ Exc (ComposeInner inner m) -> ComposeInner inner m a
handler (Exc (ComposeInner inner m) -> ComposeInner inner m a)
-> Exc (ComposeInner inner m) -> ComposeInner inner m a
forall a b. (a -> b) -> a -> b
$ Exc m -> Either (Exc inner) (Exc m)
forall a b. b -> Either a b
Right Exc m
e
                SuccessResult (FailureResult Exc inner
e) -> ComposeInner inner m a -> m (inner a)
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
ComposeInner inner outer a -> outer (inner a)
unComposeInner (ComposeInner inner m a -> m (inner a))
-> ComposeInner inner m a -> m (inner a)
forall a b. (a -> b) -> a -> b
$ Exc (ComposeInner inner m) -> ComposeInner inner m a
handler (Exc (ComposeInner inner m) -> ComposeInner inner m a)
-> Exc (ComposeInner inner m) -> ComposeInner inner m a
forall a b. (a -> b) -> a -> b
$ Exc inner -> Either (Exc inner) (Exc m)
forall a b. a -> Either a b
Left Exc inner
e
                SuccessResult (SuccessResult a
a) -> inner a -> m (inner a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (inner a -> m (inner a)) -> inner a -> m (inner a)
forall a b. (a -> b) -> a -> b
$ a -> inner a
forall a. a -> inner a
forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a

instance forall inner. (MonadInner inner, MonadException inner) => TransConstraint MonadException (ComposeInner inner) where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadException m =>
Dict (MonadException (ComposeInner inner m))
hasTransConstraint = Dict (MonadException (ComposeInner inner m))
forall (a :: Constraint). a => Dict a
Dict

instance forall inner. MonadInner inner => MonadTrans (ComposeInner inner) where
    lift :: forall (m :: Type -> Type) a.
Monad m =>
m a -> ComposeInner inner m a
lift m a
ma = m (inner a) -> ComposeInner inner m a
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (m (inner a) -> ComposeInner inner m a)
-> m (inner a) -> ComposeInner inner m a
forall a b. (a -> b) -> a -> b
$ (a -> inner a) -> m a -> m (inner 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 a -> inner a
forall a. a -> inner a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure m a
ma

instance forall inner. MonadInner inner => MonadTransHoist (ComposeInner inner) where
    hoist :: forall (m1 :: Type -> Type) (m2 :: Type -> Type).
(Monad m1, Monad m2) =>
(m1 --> m2) -> ComposeInner inner m1 --> ComposeInner inner m2
hoist m1 --> m2
ii (MkComposeInner m1 (inner a)
ma) = m2 (inner a) -> ComposeInner inner m2 a
forall (inner :: Type -> Type) (outer :: Type -> Type) a.
outer (inner a) -> ComposeInner inner outer a
MkComposeInner (m2 (inner a) -> ComposeInner inner m2 a)
-> m2 (inner a) -> ComposeInner inner m2 a
forall a b. (a -> b) -> a -> b
$ m1 (inner a) -> m2 (inner a)
m1 --> m2
ii m1 (inner a)
ma