| License | BSD |
|---|---|
| Maintainer | wren@community.haskell.org |
| Stability | provisional |
| Portability | semi-portable (CPP, Rank2Types, MPTCs, FlexibleInstances) |
| Safe Haskell | Safe-Inferred |
| Language | Haskell98 |
Control.Monad.EitherK
Description
A continuation-passing variant of Either for short-circuiting
at failure. This code is based on Control.Monad.MaybeK.
Synopsis
- data EitherK e a
- runEitherK :: EitherK e a -> Either e a
- toEitherK :: Either e a -> EitherK e a
- eitherK :: (e -> b) -> (a -> b) -> EitherK e a -> b
- throwEitherK :: e -> EitherK e a
- catchEitherK :: EitherK e a -> (e -> EitherK f a) -> EitherK f a
- data EitherKT e m a
- runEitherKT :: Applicative m => EitherKT e m a -> m (Either e a)
- toEitherKT :: Applicative m => Either e a -> EitherKT e m a
- liftEitherK :: Applicative m => EitherK e a -> EitherKT e m a
- lowerEitherK :: Applicative m => EitherKT e m a -> m (EitherK e a)
- throwEitherKT :: Applicative m => e -> EitherKT e m a
- catchEitherKT :: (Applicative m, Monad m) => EitherKT e m a -> (e -> EitherKT f m a) -> EitherKT f m a
The short-circuiting monad
A continuation-passing encoding of Either as an error monad;
also known as Codensity (Either e), if you're familiar with
that terminology. N.B., this is not the 2-continuation implementation
based on the Church encoding of Either. The latter tends to
have worse performance than non-continuation based implementations.
This is generally more efficient than using Either (or the
MTL's Error) for two reasons. First is that it right associates
all binds, ensuring that bad associativity doesn't artificially
introduce midpoints in short-circuiting to the nearest handler.
Second is that it removes the need for intermediate case
expressions.
Another benefit over MTL's Error is that it doesn't artificially
restrict the error type. In fact, there's no reason why e must
denote "errors" per se. This could also denote computations
which short-circuit with the final answer, or similar methods
of non-local control flow.
N.B., the Alternative and MonadPlus instances are left-biased
in a and monoidal in e. Thus, they are not commutative.
Instances
| MonadError e (EitherK e) Source # | |
Defined in Control.Monad.EitherK Methods throwError :: e -> EitherK e a # catchError :: EitherK e a -> (e -> EitherK e a) -> EitherK e a # | |
| Monad (EitherK e) Source # | |
| Functor (EitherK e) Source # | |
| Applicative (EitherK e) Source # | |
| Monoid e => Alternative (EitherK e) Source # | |
| Monoid e => MonadPlus (EitherK e) Source # | |
runEitherK :: EitherK e a -> Either e a Source #
Execute an EitherK and return the concrete Either encoding.
eitherK :: (e -> b) -> (a -> b) -> EitherK e a -> b Source #
A version of either on EitherK, for convenience. N.B.,
using this function inserts a case match, reducing the range of
short-circuiting.
throwEitherK :: e -> EitherK e a Source #
Throw an error in the EitherK monad. This is identical to
throwError.
catchEitherK :: EitherK e a -> (e -> EitherK f a) -> EitherK f a Source #
Handle errors in the EitherK monad. N.B., this type is more
general than that of catchError, allowing the type of the
errors to change.
The short-circuiting monad transformer
A monad transformer version of EitherK.
Instances
| (Applicative m, Monad m) => MonadError e (EitherKT e m) Source # | |
Defined in Control.Monad.EitherK Methods throwError :: e -> EitherKT e m a # catchError :: EitherKT e m a -> (e -> EitherKT e m a) -> EitherKT e m a # | |
| MonadTrans (EitherKT e) Source # | |
Defined in Control.Monad.EitherK | |
| Monad (EitherKT e m) Source # | |
| Functor (EitherKT e m) Source # | |
| Applicative (EitherKT e m) Source # | |
Defined in Control.Monad.EitherK | |
| (Applicative m, Monad m, Monoid e) => Alternative (EitherKT e m) Source # | |
| (Applicative m, Monad m, Monoid e) => MonadPlus (EitherKT e m) Source # | |
runEitherKT :: Applicative m => EitherKT e m a -> m (Either e a) Source #
Execute an EitherKT and return the concrete Either encoding.
toEitherKT :: Applicative m => Either e a -> EitherKT e m a Source #
Lift an Either into an EitherKT.
liftEitherK :: Applicative m => EitherK e a -> EitherKT e m a Source #
Lift an EitherK into an EitherKT.
lowerEitherK :: Applicative m => EitherKT e m a -> m (EitherK e a) Source #
Lower an EitherKT into an EitherK.
throwEitherKT :: Applicative m => e -> EitherKT e m a Source #
Throw an error in the EitherKT monad. This is identical to
throwError.
catchEitherKT :: (Applicative m, Monad m) => EitherKT e m a -> (e -> EitherKT f m a) -> EitherKT f m a Source #
Handle errors in the EitherKT monad. N.B., this type is more
general than that of catchError, allowing the type of the
errors to change.