{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
module Control.Monad.Trans.Either (
EitherT
, pattern EitherT
, newEitherT
, runEitherT
, eitherT
, left
, right
, mapEitherT
, hoistEither
, bimapEitherT
, firstEitherT
, secondEitherT
, hoistMaybe
, hoistEitherT
, handleIOEitherT
, handleEitherT
, handlesEitherT
, handleLeftT
, catchIOEitherT
, catchEitherT
, catchesEitherT
, catchLeftT
, bracketEitherT
, bracketExceptionT
, hushM
, onLeft
, onNothing
) where
import Control.Exception (Exception, IOException, SomeException)
import qualified Control.Exception as Exception
import Control.Monad (Monad (..), (=<<))
import Control.Monad.Catch (Handler (..), MonadCatch, MonadMask, catchAll, mask, throwM)
import qualified Control.Monad.Catch as Catch
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Except (ExceptT (..))
import Data.Either (Either (..), either)
import Data.Foldable (Foldable, foldr)
import Data.Function (const, flip, id, ($), (.))
import Data.Functor (Functor (..))
import Data.Maybe (Maybe (..), maybe)
import System.IO (IO)
type EitherT = ExceptT
pattern EitherT :: m (Either x a) -> ExceptT x m a
pattern $bEitherT :: forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
$mEitherT :: forall {r} {m :: * -> *} {x} {a}.
ExceptT x m a -> (m (Either x a) -> r) -> ((# #) -> r) -> r
EitherT m = ExceptT m
runEitherT :: EitherT x m a -> m (Either x a)
runEitherT :: forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT (ExceptT m (Either x a)
m) = m (Either x a)
m
{-# INLINE runEitherT #-}
newEitherT :: m (Either x a) -> EitherT x m a
newEitherT :: forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newEitherT =
forall e (m :: * -> *) a. m (Either e a) -> ExceptT e m a
ExceptT
{-# INLINE newEitherT #-}
eitherT :: Monad m => (x -> m b) -> (a -> m b) -> EitherT x m a -> m b
eitherT :: forall (m :: * -> *) x b a.
Monad m =>
(x -> m b) -> (a -> m b) -> EitherT x m a -> m b
eitherT x -> m b
f a -> m b
g EitherT x m a
m =
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either x -> m b
f a -> m b
g forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT EitherT x m a
m
{-# INLINE eitherT #-}
left :: Monad m => x -> EitherT x m a
left :: forall (m :: * -> *) x a. Monad m => x -> EitherT x m a
left =
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
EitherT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left
{-# INLINE left #-}
right :: Monad m => a -> EitherT x m a
right :: forall (m :: * -> *) a x. Monad m => a -> EitherT x m a
right =
forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINE right #-}
mapEitherT :: (m (Either x a) -> n (Either y b)) -> EitherT x m a -> EitherT y n b
mapEitherT :: forall (m :: * -> *) x a (n :: * -> *) y b.
(m (Either x a) -> n (Either y b))
-> EitherT x m a -> EitherT y n b
mapEitherT m (Either x a) -> n (Either y b)
f =
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
EitherT forall b c a. (b -> c) -> (a -> b) -> a -> c
. m (Either x a) -> n (Either y b)
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT
{-# INLINE mapEitherT #-}
hoistEither :: Monad m => Either x a -> EitherT x m a
hoistEither :: forall (m :: * -> *) x a. Monad m => Either x a -> EitherT x m a
hoistEither =
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
EitherT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINE hoistEither #-}
bimapEitherT :: Functor m => (x -> y) -> (a -> b) -> EitherT x m a -> EitherT y m b
bimapEitherT :: forall (m :: * -> *) x y a b.
Functor m =>
(x -> y) -> (a -> b) -> EitherT x m a -> EitherT y m b
bimapEitherT x -> y
f a -> b
g =
let
h :: Either x a -> Either y b
h (Left x
e) = forall a b. a -> Either a b
Left (x -> y
f x
e)
h (Right a
a) = forall a b. b -> Either a b
Right (a -> b
g a
a)
in
forall (m :: * -> *) x a (n :: * -> *) y b.
(m (Either x a) -> n (Either y b))
-> EitherT x m a -> EitherT y n b
mapEitherT (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either x a -> Either y b
h)
{-# INLINE bimapEitherT #-}
firstEitherT :: Functor m => (x -> y) -> EitherT x m a -> EitherT y m a
firstEitherT :: forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> EitherT x m a -> EitherT y m a
firstEitherT x -> y
f =
forall (m :: * -> *) x y a b.
Functor m =>
(x -> y) -> (a -> b) -> EitherT x m a -> EitherT y m b
bimapEitherT x -> y
f forall a. a -> a
id
{-# INLINE firstEitherT #-}
secondEitherT :: Functor m => (a -> b) -> EitherT x m a -> EitherT x m b
secondEitherT :: forall (m :: * -> *) a b x.
Functor m =>
(a -> b) -> EitherT x m a -> EitherT x m b
secondEitherT =
forall (m :: * -> *) x y a b.
Functor m =>
(x -> y) -> (a -> b) -> EitherT x m a -> EitherT y m b
bimapEitherT forall a. a -> a
id
{-# INLINE secondEitherT #-}
hoistMaybe :: Monad m => x -> Maybe a -> EitherT x m a
hoistMaybe :: forall (m :: * -> *) x a. Monad m => x -> Maybe a -> EitherT x m a
hoistMaybe x
x =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) x a. Monad m => x -> EitherT x m a
left x
x) forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINE hoistMaybe #-}
hoistEitherT :: (forall b. m b -> n b) -> EitherT x m a -> EitherT x n a
hoistEitherT :: forall (m :: * -> *) (n :: * -> *) x a.
(forall b. m b -> n b) -> EitherT x m a -> EitherT x n a
hoistEitherT forall b. m b -> n b
f =
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
EitherT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b. m b -> n b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT
{-# INLINE hoistEitherT #-}
handleIOEitherT :: MonadIO m => (IOException -> x) -> IO a -> EitherT x m a
handleIOEitherT :: forall (m :: * -> *) x a.
MonadIO m =>
(IOException -> x) -> IO a -> EitherT x m a
handleIOEitherT IOException -> x
wrap =
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> EitherT x m a -> EitherT y m a
firstEitherT IOException -> x
wrap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newEitherT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e a. Exception e => IO a -> IO (Either e a)
Exception.try
{-# INLINE handleIOEitherT #-}
catchIOEitherT :: MonadIO m => IO a -> (IOException -> x) -> EitherT x m a
catchIOEitherT :: forall (m :: * -> *) a x.
MonadIO m =>
IO a -> (IOException -> x) -> EitherT x m a
catchIOEitherT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) x a.
MonadIO m =>
(IOException -> x) -> IO a -> EitherT x m a
handleIOEitherT
{-# INLINE catchIOEitherT #-}
handleEitherT :: (MonadCatch m, Exception e) => (e -> x) -> m a -> EitherT x m a
handleEitherT :: forall (m :: * -> *) e x a.
(MonadCatch m, Exception e) =>
(e -> x) -> m a -> EitherT x m a
handleEitherT e -> x
wrap =
forall (m :: * -> *) x y a.
Functor m =>
(x -> y) -> EitherT x m a -> EitherT y m a
firstEitherT e -> x
wrap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newEitherT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
Catch.try
{-# INLINE handleEitherT #-}
catchEitherT :: (MonadCatch m, Exception e) => m a -> (e -> x) -> EitherT x m a
catchEitherT :: forall (m :: * -> *) e a x.
(MonadCatch m, Exception e) =>
m a -> (e -> x) -> EitherT x m a
catchEitherT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) e x a.
(MonadCatch m, Exception e) =>
(e -> x) -> m a -> EitherT x m a
handleEitherT
{-# INLINE catchEitherT #-}
handlesEitherT :: (Foldable f, MonadCatch m) => f (Handler m x) -> m a -> EitherT x m a
handlesEitherT :: forall (f :: * -> *) (m :: * -> *) x a.
(Foldable f, MonadCatch m) =>
f (Handler m x) -> m a -> EitherT x m a
handlesEitherT f (Handler m x)
wrappers m a
action =
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
newEitherT (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. b -> Either a b
Right m a
action forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> (e -> m a) -> m a
`Catch.catch` forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. a -> Either a b
Left) SomeException -> m x
handler)
where
handler :: SomeException -> m x
handler SomeException
e =
let probe :: Handler m a -> m a -> m a
probe (Handler e -> m a
h) m a
xs =
forall b a. b -> (a -> b) -> Maybe a -> b
maybe m a
xs e -> m a
h (forall e. Exception e => SomeException -> Maybe e
Exception.fromException SomeException
e)
in
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall {m :: * -> *} {a}. Handler m a -> m a -> m a
probe (forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
Catch.throwM SomeException
e) f (Handler m x)
wrappers
catchesEitherT :: (Foldable f, MonadCatch m) => m a -> f (Handler m x) -> EitherT x m a
catchesEitherT :: forall (f :: * -> *) (m :: * -> *) a x.
(Foldable f, MonadCatch m) =>
m a -> f (Handler m x) -> EitherT x m a
catchesEitherT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) (m :: * -> *) x a.
(Foldable f, MonadCatch m) =>
f (Handler m x) -> m a -> EitherT x m a
handlesEitherT
{-# INLINE catchesEitherT #-}
handleLeftT :: Monad m => (e -> EitherT e m a) -> EitherT e m a -> EitherT e m a
handleLeftT :: forall (m :: * -> *) e a.
Monad m =>
(e -> EitherT e m a) -> EitherT e m a -> EitherT e m a
handleLeftT e -> EitherT e m a
handler EitherT e m a
thing = do
Either e a
r <- forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT EitherT e m a
thing
case Either e a
r of
Left e
e ->
e -> EitherT e m a
handler e
e
Right a
a ->
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
{-# INLINE handleLeftT #-}
catchLeftT :: Monad m => EitherT e m a -> (e -> EitherT e m a) -> EitherT e m a
catchLeftT :: forall (m :: * -> *) e a.
Monad m =>
EitherT e m a -> (e -> EitherT e m a) -> EitherT e m a
catchLeftT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) e a.
Monad m =>
(e -> EitherT e m a) -> EitherT e m a -> EitherT e m a
handleLeftT
{-# INLINE catchLeftT #-}
bracketEitherT :: Monad m => EitherT e m a -> (a -> EitherT e m b) -> (a -> EitherT e m c) -> EitherT e m c
bracketEitherT :: forall (m :: * -> *) e a b c.
Monad m =>
EitherT e m a
-> (a -> EitherT e m b) -> (a -> EitherT e m c) -> EitherT e m c
bracketEitherT EitherT e m a
before a -> EitherT e m b
after a -> EitherT e m c
thing = do
a
a <- EitherT e m a
before
c
r <- (\e
err -> a -> EitherT e m b
after a
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) x a. Monad m => x -> EitherT x m a
left e
err) forall (m :: * -> *) e a.
Monad m =>
(e -> EitherT e m a) -> EitherT e m a -> EitherT e m a
`handleLeftT` a -> EitherT e m c
thing a
a
b
_ <- a -> EitherT e m b
after a
a
forall (m :: * -> *) a. Monad m => a -> m a
return c
r
{-# INLINE bracketEitherT #-}
bracketExceptionT ::
MonadMask m
=> EitherT e m a
-> (a -> EitherT e m c)
-> (a -> EitherT e m b)
-> EitherT e m b
bracketExceptionT :: forall (m :: * -> *) e a c b.
MonadMask m =>
EitherT e m a
-> (a -> EitherT e m c) -> (a -> EitherT e m b) -> EitherT e m b
bracketExceptionT EitherT e m a
acquire a -> EitherT e m c
release a -> EitherT e m b
run =
forall (m :: * -> *) x a. m (Either x a) -> ExceptT x m a
EitherT forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a b c.
MonadMask m =>
m a -> (a -> m (Either b c)) -> (a -> m b) -> m b
bracketF
(forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT EitherT e m a
acquire)
(\Either e a
r -> case Either e a
r of
Left e
_ ->
forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ ()
Right a
r' ->
forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT (a -> EitherT e m c
release a
r') forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Either e c
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Either e c
x of
Left e
err -> forall a b. a -> Either a b
Left (forall a b. a -> Either a b
Left e
err)
Right c
_ -> forall a b. b -> Either a b
Right ())
(\Either e a
r -> case Either e a
r of
Left e
err ->
forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ e
err
Right a
r' ->
forall x (m :: * -> *) a. EitherT x m a -> m (Either x a)
runEitherT (a -> EitherT e m b
run a
r'))
{-# INLINE bracketExceptionT #-}
data BracketResult a =
BracketOk a
| BracketFailedFinalizerOk SomeException
| BracketFailedFinalizerError a
bracketF :: MonadMask m => m a -> (a -> m (Either b c)) -> (a -> m b) -> m b
bracketF :: forall (m :: * -> *) a b c.
MonadMask m =>
m a -> (a -> m (Either b c)) -> (a -> m b) -> m b
bracketF m a
a a -> m (Either b c)
f a -> m b
g =
forall (m :: * -> *) b.
MonadMask m =>
((forall a. m a -> m a) -> m b) -> m b
mask forall a b. (a -> b) -> a -> b
$ \forall a. m a -> m a
restore -> do
a
a' <- m a
a
BracketResult b
x <- forall a. m a -> m a
restore (forall a. a -> BracketResult a
BracketOk forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` a -> m b
g a
a') forall (m :: * -> *) a.
MonadCatch m =>
m a -> (SomeException -> m a) -> m a
`catchAll`
(\SomeException
ex -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> BracketResult a
BracketFailedFinalizerError (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall a. SomeException -> BracketResult a
BracketFailedFinalizerOk SomeException
ex) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` a -> m (Either b c)
f a
a')
case BracketResult b
x of
BracketFailedFinalizerOk SomeException
ex ->
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM SomeException
ex
BracketFailedFinalizerError b
b ->
forall (m :: * -> *) a. Monad m => a -> m a
return b
b
BracketOk b
b -> do
Either b c
z <- a -> m (Either b c)
f a
a'
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id (forall a b. a -> b -> a
const b
b) Either b c
z
{-# INLINE bracketF #-}
hushM :: Monad m => Either e a -> (e -> m ()) -> m (Maybe a)
hushM :: forall (m :: * -> *) e a.
Monad m =>
Either e a -> (e -> m ()) -> m (Maybe a)
hushM Either e a
r e -> m ()
f = case Either e a
r of
Right a
a -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just a
a)
Left e
e -> e -> m ()
f e
e forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
{-# INLINE hushM #-}
onLeft :: forall e x m a. Monad m => (e -> ExceptT x m a) -> EitherT x m (Either e a) -> EitherT x m a
onLeft :: forall e x (m :: * -> *) a.
Monad m =>
(e -> ExceptT x m a) -> EitherT x m (Either e a) -> ExceptT x m a
onLeft e -> ExceptT x m a
h EitherT x m (Either e a)
f = EitherT x m (Either e a)
f forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either e -> ExceptT x m a
h forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINE onLeft #-}
onNothing :: forall x m a. Monad m => EitherT x m a -> EitherT x m (Maybe a) -> EitherT x m a
onNothing :: forall x (m :: * -> *) a.
Monad m =>
EitherT x m a -> EitherT x m (Maybe a) -> EitherT x m a
onNothing EitherT x m a
h EitherT x m (Maybe a)
f = EitherT x m (Maybe a)
f forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe EitherT x m a
h forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINE onNothing #-}