{-# 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 = (e -> f a) -> (a -> f a) -> Either e a -> f a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either e -> f a
forall e a (f :: * -> *). SendFOE (Throw e) f => e -> f a
throw a -> f a
forall a. a -> f a
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 = (m (Either e a) -> (Either e a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (e -> m a) -> (a -> m a) -> Either e a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either e -> m a
forall e a (f :: * -> *). SendFOE (Throw e) f => e -> f a
throw a -> m a
forall a. a -> m a
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 = (m a -> m a) -> (a -> m a) -> Either (m a) a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either m a -> m a
forall a. a -> a
id a -> m a
forall a. a -> m a
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 = (m (Either (m a) a) -> (Either (m a) a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (m a -> m a) -> (a -> m a) -> Either (m a) a -> m a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either m a -> m a
forall a. a -> a
id a -> m a
forall a. a -> m a
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 f a -> (e -> f a) -> f a
forall a e (f :: * -> *).
SendHOE (Catch e) f =>
f a -> (e -> f a) -> f a
`catch` \e
e -> e -> f ()
after e
e f () -> f a -> f a
forall a b. f a -> f b -> f b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> e -> f a
forall e a (f :: * -> *). SendFOE (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 f a -> (e -> f ()) -> f a
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 #-}