{-# 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 = forall (a :: Constraint). a => Dict a
Dict

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

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

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

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

instance TransConstraint MonadPlus MaybeT where
    hasTransConstraint :: forall (m :: Type -> Type).
MonadPlus m =>
Dict (MonadPlus (MaybeT m))
hasTransConstraint = 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 = forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    throwExc (Just Exc m
e) = forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT 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.
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 =
        forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT forall a b. (a -> b) -> a -> b
$ do
            Result (Exc m) (Maybe a)
ea <- 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 -> forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT forall a b. (a -> b) -> a -> b
$ Exc (MaybeT m) -> MaybeT m a
handler forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Exc m
e
                SuccessResult Maybe a
Nothing -> forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT forall a b. (a -> b) -> a -> b
$ Exc (MaybeT m) -> MaybeT m a
handler forall a. Maybe a
Nothing
                SuccessResult (Just 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 MonadThrow e m => MonadThrow (Maybe e) (MaybeT m) where
    throw :: forall a. Maybe e -> MaybeT m a
throw Maybe e
Nothing = forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
    throw (Just e
e) = forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT forall a b. (a -> b) -> a -> b
$ 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 =
        forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT forall a b. (a -> b) -> a -> b
$ do
            Result e (Maybe a)
ea <- 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 -> forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT forall a b. (a -> b) -> a -> b
$ Maybe e -> MaybeT m a
handler forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just e
e
                SuccessResult Maybe a
Nothing -> forall (m :: Type -> Type) a. MaybeT m a -> m (Maybe a)
runMaybeT forall a b. (a -> b) -> a -> b
$ Maybe e -> MaybeT m a
handler forall a. Maybe a
Nothing
                SuccessResult (Just 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 MonadInner m => MonadInner (MaybeT m) where
    retrieveInner :: forall a. MaybeT m a -> Result (Exc (MaybeT m)) a
retrieveInner (MaybeT m (Maybe a)
mma) =
        case forall (m :: Type -> Type) a.
MonadInner m =>
m a -> Result (Exc m) a
retrieveInner m (Maybe a)
mma of
            SuccessResult (Just a
a) -> forall e a. a -> Result e a
SuccessResult a
a
            SuccessResult Maybe a
Nothing -> forall e a. e -> Result e a
FailureResult forall a. Maybe a
Nothing
            FailureResult Exc m
e -> forall e a. e -> Result e a
FailureResult forall a b. (a -> b) -> a -> b
$ 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 = 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 = 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 = 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 = forall (m :: Type -> Type) a. m (Maybe a) -> MaybeT m a
MaybeT 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 a b. (a -> b) -> a -> b
$ \(MaybeT m1 (Maybe a)
ma) -> m1 (Maybe a)
ma