{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
Here we implement a monad transformer
which adds exception handling and
labelling of actions (using "Control.Monad.Label")
in order to extend exceptions with a kind of call stack.
-}
module Control.Monad.Exception.Label where

import qualified Control.Monad.Exception.Synchronous as Exception
import qualified Control.Monad.Label as Label

import Control.Monad.Exception.Synchronous (ExceptionalT, mapExceptionT, )
import Control.Monad.Label (LabelT, )
import Control.Applicative (Applicative, )

import Control.Monad (liftM, )
import Control.Monad.Fix (MonadFix, )
import Control.Monad.Trans.Class (MonadTrans, lift, )


data LabeledException l e =
   LabeledException {LabeledException l e -> [l]
labels :: [l], LabeledException l e -> e
exception :: e}

newtype LabeledExceptionalT l e m a =
   LabeledExceptionalT
      {LabeledExceptionalT l e m a
-> LabelT l (ExceptionalT (LabeledException l e) m) a
runLabeledExceptionalT :: LabelT l (ExceptionalT (LabeledException l e) m) a}
      deriving (a -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
(a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
(forall a b.
 (a -> b)
 -> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b)
-> (forall a b.
    a -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a)
-> Functor (LabeledExceptionalT l e m)
forall a b.
a -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
forall a b.
(a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
forall l e (m :: * -> *) a b.
Functor m =>
a -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
forall l e (m :: * -> *) a b.
Functor m =>
(a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
$c<$ :: forall l e (m :: * -> *) a b.
Functor m =>
a -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
fmap :: (a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
$cfmap :: forall l e (m :: * -> *) a b.
Functor m =>
(a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
Functor, Functor (LabeledExceptionalT l e m)
a -> LabeledExceptionalT l e m a
Functor (LabeledExceptionalT l e m) =>
(forall a. a -> LabeledExceptionalT l e m a)
-> (forall a b.
    LabeledExceptionalT l e m (a -> b)
    -> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b)
-> (forall a b c.
    (a -> b -> c)
    -> LabeledExceptionalT l e m a
    -> LabeledExceptionalT l e m b
    -> LabeledExceptionalT l e m c)
-> (forall a b.
    LabeledExceptionalT l e m a
    -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b)
-> (forall a b.
    LabeledExceptionalT l e m a
    -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a)
-> Applicative (LabeledExceptionalT l e m)
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
LabeledExceptionalT l e m (a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
(a -> b -> c)
-> LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b
-> LabeledExceptionalT l e m c
forall a. a -> LabeledExceptionalT l e m a
forall a b.
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
forall a b.
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
forall a b.
LabeledExceptionalT l e m (a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
forall a b c.
(a -> b -> c)
-> LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b
-> LabeledExceptionalT l e m c
forall l e (m :: * -> *).
Applicative m =>
Functor (LabeledExceptionalT l e m)
forall l e (m :: * -> *) a.
Applicative m =>
a -> LabeledExceptionalT l e m a
forall l e (m :: * -> *) a b.
Applicative m =>
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
forall l e (m :: * -> *) a b.
Applicative m =>
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
forall l e (m :: * -> *) a b.
Applicative m =>
LabeledExceptionalT l e m (a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
forall l e (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b
-> LabeledExceptionalT l e m c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
$c<* :: forall l e (m :: * -> *) a b.
Applicative m =>
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m a
*> :: LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
$c*> :: forall l e (m :: * -> *) a b.
Applicative m =>
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
liftA2 :: (a -> b -> c)
-> LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b
-> LabeledExceptionalT l e m c
$cliftA2 :: forall l e (m :: * -> *) a b c.
Applicative m =>
(a -> b -> c)
-> LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b
-> LabeledExceptionalT l e m c
<*> :: LabeledExceptionalT l e m (a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
$c<*> :: forall l e (m :: * -> *) a b.
Applicative m =>
LabeledExceptionalT l e m (a -> b)
-> LabeledExceptionalT l e m a -> LabeledExceptionalT l e m b
pure :: a -> LabeledExceptionalT l e m a
$cpure :: forall l e (m :: * -> *) a.
Applicative m =>
a -> LabeledExceptionalT l e m a
$cp1Applicative :: forall l e (m :: * -> *).
Applicative m =>
Functor (LabeledExceptionalT l e m)
Applicative, Applicative (LabeledExceptionalT l e m)
a -> LabeledExceptionalT l e m a
Applicative (LabeledExceptionalT l e m) =>
(forall a b.
 LabeledExceptionalT l e m a
 -> (a -> LabeledExceptionalT l e m b)
 -> LabeledExceptionalT l e m b)
-> (forall a b.
    LabeledExceptionalT l e m a
    -> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b)
-> (forall a. a -> LabeledExceptionalT l e m a)
-> Monad (LabeledExceptionalT l e m)
LabeledExceptionalT l e m a
-> (a -> LabeledExceptionalT l e m b)
-> LabeledExceptionalT l e m b
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
forall a. a -> LabeledExceptionalT l e m a
forall a b.
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
forall a b.
LabeledExceptionalT l e m a
-> (a -> LabeledExceptionalT l e m b)
-> LabeledExceptionalT l e m b
forall l e (m :: * -> *).
Monad m =>
Applicative (LabeledExceptionalT l e m)
forall l e (m :: * -> *) a.
Monad m =>
a -> LabeledExceptionalT l e m a
forall l e (m :: * -> *) a b.
Monad m =>
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
forall l e (m :: * -> *) a b.
Monad m =>
LabeledExceptionalT l e m a
-> (a -> LabeledExceptionalT l e m b)
-> LabeledExceptionalT l e m b
forall (m :: * -> *).
Applicative m =>
(forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> LabeledExceptionalT l e m a
$creturn :: forall l e (m :: * -> *) a.
Monad m =>
a -> LabeledExceptionalT l e m a
>> :: LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
$c>> :: forall l e (m :: * -> *) a b.
Monad m =>
LabeledExceptionalT l e m a
-> LabeledExceptionalT l e m b -> LabeledExceptionalT l e m b
>>= :: LabeledExceptionalT l e m a
-> (a -> LabeledExceptionalT l e m b)
-> LabeledExceptionalT l e m b
$c>>= :: forall l e (m :: * -> *) a b.
Monad m =>
LabeledExceptionalT l e m a
-> (a -> LabeledExceptionalT l e m b)
-> LabeledExceptionalT l e m b
$cp1Monad :: forall l e (m :: * -> *).
Monad m =>
Applicative (LabeledExceptionalT l e m)
Monad, Monad (LabeledExceptionalT l e m)
Monad (LabeledExceptionalT l e m) =>
(forall a.
 (a -> LabeledExceptionalT l e m a) -> LabeledExceptionalT l e m a)
-> MonadFix (LabeledExceptionalT l e m)
(a -> LabeledExceptionalT l e m a) -> LabeledExceptionalT l e m a
forall a.
(a -> LabeledExceptionalT l e m a) -> LabeledExceptionalT l e m a
forall l e (m :: * -> *).
MonadFix m =>
Monad (LabeledExceptionalT l e m)
forall l e (m :: * -> *) a.
MonadFix m =>
(a -> LabeledExceptionalT l e m a) -> LabeledExceptionalT l e m a
forall (m :: * -> *).
Monad m =>
(forall a. (a -> m a) -> m a) -> MonadFix m
mfix :: (a -> LabeledExceptionalT l e m a) -> LabeledExceptionalT l e m a
$cmfix :: forall l e (m :: * -> *) a.
MonadFix m =>
(a -> LabeledExceptionalT l e m a) -> LabeledExceptionalT l e m a
$cp1MonadFix :: forall l e (m :: * -> *).
MonadFix m =>
Monad (LabeledExceptionalT l e m)
MonadFix)


runLabelT :: (Monad m) =>
   LabeledExceptionalT l e m a ->
   [l] ->
   ExceptionalT (LabeledException l e) m a
runLabelT :: LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
runLabelT =
   LabelT l (ExceptionalT (LabeledException l e) m) a
-> [l] -> ExceptionalT (LabeledException l e) m a
forall (m :: * -> *) l a. Monad m => LabelT l m a -> [l] -> m a
Label.runLabelT (LabelT l (ExceptionalT (LabeledException l e) m) a
 -> [l] -> ExceptionalT (LabeledException l e) m a)
-> (LabeledExceptionalT l e m a
    -> LabelT l (ExceptionalT (LabeledException l e) m) a)
-> LabeledExceptionalT l e m a
-> [l]
-> ExceptionalT (LabeledException l e) m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabeledExceptionalT l e m a
-> LabelT l (ExceptionalT (LabeledException l e) m) a
forall l e (m :: * -> *) a.
LabeledExceptionalT l e m a
-> LabelT l (ExceptionalT (LabeledException l e) m) a
runLabeledExceptionalT

labelT :: (Monad m) =>
   ExceptionalT (LabeledException l e) m a ->
   LabeledExceptionalT l e m a
labelT :: ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
labelT =
   LabelT l (ExceptionalT (LabeledException l e) m) a
-> LabeledExceptionalT l e m a
forall l e (m :: * -> *) a.
LabelT l (ExceptionalT (LabeledException l e) m) a
-> LabeledExceptionalT l e m a
LabeledExceptionalT (LabelT l (ExceptionalT (LabeledException l e) m) a
 -> LabeledExceptionalT l e m a)
-> (ExceptionalT (LabeledException l e) m a
    -> LabelT l (ExceptionalT (LabeledException l e) m) a)
-> ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptionalT (LabeledException l e) m a
-> LabelT l (ExceptionalT (LabeledException l e) m) a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift -- Label.LabelT . ReaderT


stripLabelT :: (Monad m) =>
   LabeledExceptionalT l e m a -> ExceptionalT e m a
stripLabelT :: LabeledExceptionalT l e m a -> ExceptionalT e m a
stripLabelT action :: LabeledExceptionalT l e m a
action =
   (LabeledException l e -> e)
-> ExceptionalT (LabeledException l e) m a -> ExceptionalT e m a
forall (m :: * -> *) e0 e1 a.
Monad m =>
(e0 -> e1) -> ExceptionalT e0 m a -> ExceptionalT e1 m a
mapExceptionT LabeledException l e -> e
forall l e. LabeledException l e -> e
exception (LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
forall (m :: * -> *) l e a.
Monad m =>
LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
runLabelT LabeledExceptionalT l e m a
action [])

decorateLabelT :: (Monad m) =>
   ExceptionalT e m a -> LabeledExceptionalT l e m a
decorateLabelT :: ExceptionalT e m a -> LabeledExceptionalT l e m a
decorateLabelT =
   ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall (m :: * -> *) l e a.
Monad m =>
ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
labelT (ExceptionalT (LabeledException l e) m a
 -> LabeledExceptionalT l e m a)
-> (ExceptionalT e m a -> ExceptionalT (LabeledException l e) m a)
-> ExceptionalT e m a
-> LabeledExceptionalT l e m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> LabeledException l e)
-> ExceptionalT e m a -> ExceptionalT (LabeledException l e) m a
forall (m :: * -> *) e0 e1 a.
Monad m =>
(e0 -> e1) -> ExceptionalT e0 m a -> ExceptionalT e1 m a
mapExceptionT ([l] -> e -> LabeledException l e
forall l e. [l] -> e -> LabeledException l e
LabeledException [])

getLabels :: (Monad m) =>
   LabeledExceptionalT l e m [l]
getLabels :: LabeledExceptionalT l e m [l]
getLabels = LabelT l (ExceptionalT (LabeledException l e) m) [l]
-> LabeledExceptionalT l e m [l]
forall l e (m :: * -> *) a.
LabelT l (ExceptionalT (LabeledException l e) m) a
-> LabeledExceptionalT l e m a
LabeledExceptionalT (LabelT l (ExceptionalT (LabeledException l e) m) [l]
 -> LabeledExceptionalT l e m [l])
-> LabelT l (ExceptionalT (LabeledException l e) m) [l]
-> LabeledExceptionalT l e m [l]
forall a b. (a -> b) -> a -> b
$ LabelT l (ExceptionalT (LabeledException l e) m) [l]
forall (m :: * -> *) l. Monad m => LabelT l m [l]
Label.askT


throwT :: (Monad m) =>
   e -> LabeledExceptionalT l e m a
throwT :: e -> LabeledExceptionalT l e m a
throwT e :: e
e =
   do [l]
l <- LabeledExceptionalT l e m [l]
forall (m :: * -> *) l e. Monad m => LabeledExceptionalT l e m [l]
getLabels
      ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall (m :: * -> *) l e a.
Monad m =>
ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
labelT (ExceptionalT (LabeledException l e) m a
 -> LabeledExceptionalT l e m a)
-> ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall a b. (a -> b) -> a -> b
$ LabeledException l e -> ExceptionalT (LabeledException l e) m a
forall (m :: * -> *) e a. Monad m => e -> ExceptionalT e m a
Exception.throwT ([l] -> e -> LabeledException l e
forall l e. [l] -> e -> LabeledException l e
LabeledException [l]
l e
e)


{- |
Currently 'catchT' calls the exception handler with a full call stack.
Since 'catchT' handles exceptions locally
it may however clear the call stack before calling the inner action
and a re-throw should append the inner call stack to the outer one.
For this semantics, a difference list would be more efficient for labels.
-}
catchT :: (Monad m) =>
   LabeledExceptionalT l e0 m a ->
   ([l] -> e0 -> LabeledExceptionalT l e1 m a) ->
   LabeledExceptionalT l e1 m a
catchT :: LabeledExceptionalT l e0 m a
-> ([l] -> e0 -> LabeledExceptionalT l e1 m a)
-> LabeledExceptionalT l e1 m a
catchT action :: LabeledExceptionalT l e0 m a
action handler :: [l] -> e0 -> LabeledExceptionalT l e1 m a
handler =
   do [l]
ls <- LabeledExceptionalT l e1 m [l]
forall (m :: * -> *) l e. Monad m => LabeledExceptionalT l e m [l]
getLabels
      ExceptionalT (LabeledException l e1) m a
-> LabeledExceptionalT l e1 m a
forall (m :: * -> *) l e a.
Monad m =>
ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
labelT (ExceptionalT (LabeledException l e1) m a
 -> LabeledExceptionalT l e1 m a)
-> ExceptionalT (LabeledException l e1) m a
-> LabeledExceptionalT l e1 m a
forall a b. (a -> b) -> a -> b
$ ExceptionalT (LabeledException l e0) m a
-> (LabeledException l e0
    -> ExceptionalT (LabeledException l e1) m a)
-> ExceptionalT (LabeledException l e1) m a
forall (m :: * -> *) e0 a e1.
Monad m =>
ExceptionalT e0 m a
-> (e0 -> ExceptionalT e1 m a) -> ExceptionalT e1 m a
Exception.catchT
         (LabeledExceptionalT l e0 m a
-> [l] -> ExceptionalT (LabeledException l e0) m a
forall (m :: * -> *) l e a.
Monad m =>
LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
runLabelT LabeledExceptionalT l e0 m a
action [l]
ls)
         (\(LabeledException l :: [l]
l e :: e0
e) -> LabeledExceptionalT l e1 m a
-> [l] -> ExceptionalT (LabeledException l e1) m a
forall (m :: * -> *) l e a.
Monad m =>
LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
runLabelT ([l] -> e0 -> LabeledExceptionalT l e1 m a
handler [l]
l e0
e) [l]
ls)


{- |
If the enclosed monad has custom exception facilities,
they could skip the cleanup code.
Make sure, that this cannot happen by choosing an appropriate monad.
-}
bracketT :: (Monad m) =>
   l ->
   LabeledExceptionalT l e m h ->
   (h -> LabeledExceptionalT l e m ()) ->
   (h -> LabeledExceptionalT l e m a) ->
   LabeledExceptionalT l e m a
bracketT :: l
-> LabeledExceptionalT l e m h
-> (h -> LabeledExceptionalT l e m ())
-> (h -> LabeledExceptionalT l e m a)
-> LabeledExceptionalT l e m a
bracketT label :: l
label open :: LabeledExceptionalT l e m h
open close :: h -> LabeledExceptionalT l e m ()
close action :: h -> LabeledExceptionalT l e m a
action =
   do [l]
ls <- ([l] -> [l])
-> LabeledExceptionalT l e m [l] -> LabeledExceptionalT l e m [l]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (l
labell -> [l] -> [l]
forall a. a -> [a] -> [a]
:) LabeledExceptionalT l e m [l]
forall (m :: * -> *) l e. Monad m => LabeledExceptionalT l e m [l]
getLabels
      ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall (m :: * -> *) l e a.
Monad m =>
ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
labelT (ExceptionalT (LabeledException l e) m a
 -> LabeledExceptionalT l e m a)
-> ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall a b. (a -> b) -> a -> b
$
         ExceptionalT (LabeledException l e) m h
-> (h -> ExceptionalT (LabeledException l e) m ())
-> (h -> ExceptionalT (LabeledException l e) m a)
-> ExceptionalT (LabeledException l e) m a
forall (m :: * -> *) e h a.
Monad m =>
ExceptionalT e m h
-> (h -> ExceptionalT e m ())
-> (h -> ExceptionalT e m a)
-> ExceptionalT e m a
Exception.bracketT
            (LabeledExceptionalT l e m h
-> [l] -> ExceptionalT (LabeledException l e) m h
forall (m :: * -> *) l e a.
Monad m =>
LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
runLabelT LabeledExceptionalT l e m h
open [l]
ls)
            (\h :: h
h -> LabeledExceptionalT l e m ()
-> [l] -> ExceptionalT (LabeledException l e) m ()
forall (m :: * -> *) l e a.
Monad m =>
LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
runLabelT (h -> LabeledExceptionalT l e m ()
close h
h) [l]
ls)
            (\h :: h
h -> LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
forall (m :: * -> *) l e a.
Monad m =>
LabeledExceptionalT l e m a
-> [l] -> ExceptionalT (LabeledException l e) m a
runLabelT (h -> LabeledExceptionalT l e m a
action h
h) [l]
ls)


instance MonadTrans (LabeledExceptionalT l e) where
   lift :: m a -> LabeledExceptionalT l e m a
lift m :: m a
m = ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall (m :: * -> *) l e a.
Monad m =>
ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
labelT (ExceptionalT (LabeledException l e) m a
 -> LabeledExceptionalT l e m a)
-> ExceptionalT (LabeledException l e) m a
-> LabeledExceptionalT l e m a
forall a b. (a -> b) -> a -> b
$ m a -> ExceptionalT (LabeledException l e) m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m a
m