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

module Control.Monad.Ology.Specific.MaybeT
    ( module Control.Monad.Trans.Maybe
    ) where

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

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

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

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

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

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

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

instance MonadException m => MonadException (MaybeT m) where
    type Exc (MaybeT m) = Maybe (Exc m)
    throwExc :: forall a. Exc (MaybeT m) -> MaybeT m a
throwExc Maybe (Exc m)
Exc (MaybeT m)
Nothing = m (Maybe a) -> MaybeT m a
forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
    throwExc (Just Exc m
e) = m (Maybe a) -> MaybeT m a
forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ Exc m -> m (Maybe 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.
MaybeT m a -> (Exc (MaybeT m) -> MaybeT m a) -> MaybeT m a
catchExc (MaybeT m (Maybe a)
mea) Exc (MaybeT m) -> MaybeT m a
handler =
        m (Maybe a) -> MaybeT m a
forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ do
            Result (Exc m) (Maybe a)
ea <- m (Maybe a) -> m (Result (Exc m) (Maybe a))
forall (m :: Type -> Type) a.
MonadException m =>
m a -> m (Result (Exc m) a)
tryExc m (Maybe a)
mea
            case Result (Exc m) (Maybe a)
ea of
                FailureResult Exc m
e -> MaybeT m a -> m (Maybe a)
forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m a -> m (Maybe a)) -> MaybeT m a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ Exc (MaybeT m) -> MaybeT m a
handler (Exc (MaybeT m) -> MaybeT m a) -> Exc (MaybeT m) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ Exc m -> Maybe (Exc m)
forall a. a -> Maybe a
Just Exc m
e
                SuccessResult Maybe a
Nothing -> MaybeT m a -> m (Maybe a)
forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m a -> m (Maybe a)) -> MaybeT m a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ Exc (MaybeT m) -> MaybeT m a
handler Maybe (Exc m)
Exc (MaybeT m)
forall a. Maybe a
Nothing
                SuccessResult (Just a
a) -> Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a

instance MonadThrow e m => MonadThrow (Maybe e) (MaybeT m) where
    throw :: forall a. Maybe e -> MaybeT m a
throw Maybe e
Nothing = m (Maybe a) -> MaybeT m a
forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
    throw (Just e
e) = m (Maybe a) -> MaybeT m a
forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ e -> m (Maybe a)
forall a. e -> m a
forall e (m :: Type -> Type) a. MonadThrow e m => e -> m a
throw e
e

instance MonadCatch e m => MonadCatch (Maybe e) (MaybeT m) where
    catch :: forall a. MaybeT m a -> (Maybe e -> MaybeT m a) -> MaybeT m a
catch (MaybeT m (Maybe a)
mea) Maybe e -> MaybeT m a
handler =
        m (Maybe a) -> MaybeT m a
forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe a) -> MaybeT m a) -> m (Maybe a) -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ do
            Result e (Maybe a)
ea <- m (Maybe a) -> m (Result e (Maybe a))
forall (m :: Type -> Type) e a.
MonadCatch e m =>
m a -> m (Result e a)
try m (Maybe a)
mea
            case Result e (Maybe a)
ea of
                FailureResult e
e -> MaybeT m a -> m (Maybe a)
forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m a -> m (Maybe a)) -> MaybeT m a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ Maybe e -> MaybeT m a
handler (Maybe e -> MaybeT m a) -> Maybe e -> MaybeT m a
forall a b. (a -> b) -> a -> b
$ e -> Maybe e
forall a. a -> Maybe a
Just e
e
                SuccessResult Maybe a
Nothing -> MaybeT m a -> m (Maybe a)
forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT m a -> m (Maybe a)) -> MaybeT m a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ Maybe e -> MaybeT m a
handler Maybe e
forall a. Maybe a
Nothing
                SuccessResult (Just a
a) -> Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (Maybe a -> m (Maybe a)) -> Maybe a -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
forall (m :: Type -> Type) a. Monad m => a -> m a
return a
a

instance MonadInner m => MonadInner (MaybeT m) where
    retrieveInner :: forall a. MaybeT m a -> Result (Exc (MaybeT m)) a
retrieveInner (MaybeT m (Maybe a)
mma) =
        case m (Maybe a) -> Result (Exc m) (Maybe a)
forall a. m a -> Result (Exc m) a
forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner m (Maybe a)
mma of
            SuccessResult (Just a
a) -> a -> Result (Maybe (Exc m)) a
forall e a. a -> Result e a
SuccessResult a
a
            SuccessResult Maybe a
Nothing -> Maybe (Exc m) -> Result (Maybe (Exc m)) a
forall e a. e -> Result e a
FailureResult Maybe (Exc m)
forall a. Maybe a
Nothing
            FailureResult Exc m
e -> Exc (MaybeT m) -> Result (Exc (MaybeT m)) a
forall e a. e -> Result e a
FailureResult (Exc (MaybeT m) -> Result (Exc (MaybeT m)) a)
-> Exc (MaybeT m) -> Result (Exc (MaybeT m)) a
forall a b. (a -> b) -> a -> b
$ Exc m -> Maybe (Exc m)
forall a. a -> Maybe a
Just Exc m
e

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

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

instance MonadTransHoist MaybeT where
    hoist :: forall (m1 :: Type -> Type) (m2 :: Type -> Type).
(Monad m1, Monad m2) =>
(m1 --> m2) -> MaybeT m1 --> MaybeT m2
hoist = (m1 --> m2) -> MaybeT m1 --> MaybeT 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 MaybeT where
    type Tunnel MaybeT = Maybe
    tunnel :: forall (m :: Type -> Type) r.
Monad m =>
((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  MaybeT m1 a -> m1 (Tunnel MaybeT a))
 -> m (Tunnel MaybeT r))
-> MaybeT m r
tunnel (forall (m1 :: Type -> Type) a.
 Monad m1 =>
 MaybeT m1 a -> m1 (Tunnel MaybeT a))
-> m (Tunnel MaybeT r)
call = m (Maybe r) -> MaybeT m r
forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT (m (Maybe r) -> MaybeT m r) -> m (Maybe r) -> MaybeT m r
forall a b. (a -> b) -> a -> b
$ (forall (m1 :: Type -> Type) a.
 Monad m1 =>
 MaybeT m1 a -> m1 (Tunnel MaybeT a))
-> m (Tunnel MaybeT r)
call ((forall (m1 :: Type -> Type) a.
  Monad m1 =>
  MaybeT m1 a -> m1 (Tunnel MaybeT a))
 -> m (Tunnel MaybeT r))
-> (forall (m1 :: Type -> Type) a.
    Monad m1 =>
    MaybeT m1 a -> m1 (Tunnel MaybeT a))
-> m (Tunnel MaybeT r)
forall a b. (a -> b) -> a -> b
$ \(MaybeT m1 (Maybe a)
ma) -> m1 (Maybe a)
m1 (Tunnel MaybeT a)
ma