{-# LANGUAGE AllowAmbiguousTypes #-}
module Data.Effect.Except where
data Throw e (a :: Type) where
Throw :: e -> Throw e a
data Catch e f (a :: Type) where
Catch :: f a -> (e -> f a) -> Catch e f a
makeEffect [''Throw] [''Catch]
liftEither :: (Throw e <: f, Applicative f) => Either e a -> f a
liftEither :: forall e (f :: * -> *) a.
(Throw e <: f, Applicative f) =>
Either e a -> f a
liftEither = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall e a (f :: * -> *). SendIns (Throw e) f => e -> f a
throw forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE liftEither #-}
joinEither :: (Throw e <: m, Monad m) => m (Either e a) -> m a
joinEither :: forall e (m :: * -> *) a.
(Throw e <: m, Monad m) =>
m (Either e a) -> m a
joinEither = (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 forall e a (f :: * -> *). SendIns (Throw e) f => e -> f a
throw forall (f :: * -> *) a. Applicative f => a -> f a
pure)
{-# INLINE joinEither #-}
joinExcept :: Monad m => Either (m a) a -> m a
joinExcept :: forall (m :: * -> *) a. Monad m => Either (m a) a -> m a
joinExcept = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. a -> a
id forall (f :: * -> *) a. Applicative f => a -> f a
pure
{-# INLINE joinExcept #-}
exc :: Monad m => m (Either (m a) a) -> m a
exc :: forall (m :: * -> *) a. Monad m => m (Either (m a) a) -> m a
exc = (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 forall a. a -> a
id forall (f :: * -> *) a. Applicative f => a -> f a
pure)
{-# INLINE exc #-}
withExcept :: (Catch e <<: f, Throw e <: f, Applicative f) => f a -> (e -> f ()) -> f a
withExcept :: forall e (f :: * -> *) a.
(Catch e <<: f, Throw e <: f, Applicative f) =>
f a -> (e -> f ()) -> f a
withExcept f a
thing e -> f ()
after = f a
thing forall a e (f :: * -> *).
SendSig (Catch e) f =>
f a -> (e -> f a) -> f a
`catch` \e
e -> e -> f ()
after e
e forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall e a (f :: * -> *). SendIns (Throw e) f => e -> f a
throw e
e
{-# INLINE withExcept #-}
onExcept :: forall e f a. (Catch e <<: f, Throw e <: f, Applicative f) => f a -> f () -> f a
onExcept :: forall e (f :: * -> *) a.
(Catch e <<: f, Throw e <: f, Applicative f) =>
f a -> f () -> f a
onExcept f a
thing f ()
after = f a
thing forall e (f :: * -> *) a.
(Catch e <<: f, Throw e <: f, Applicative f) =>
f a -> (e -> f ()) -> f a
`withExcept` \(e
_ :: e) -> f ()
after
{-# INLINE onExcept #-}