License | BSD |
---|---|
Maintainer | wren@community.haskell.org |
Stability | provisional |
Portability | semi-portable (CPP, Rank2Types, MPTCs, FlexibleInstances) |
Safe Haskell | Safe-Inferred |
Language | Haskell98 |
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 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 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.