L
- The left parameter typeR
- The right parameter typepublic abstract class Either<L,R> extends Object implements CoProduct2<L,R,Either<L,R>>, MonadError<L,R,Either<L,?>>, MonadRec<R,Either<L,?>>, Traversable<R,Either<L,?>>, Bifunctor<L,R,Either<?,?>>
CoProduct2
. General semantics tend to connote "success"
values via the right value and "failure" values via the left values. Either
s are both Monad
s and
Traversable
s over their right value and are Bifunctor
s over both values.Modifier and Type | Method and Description |
---|---|
<L2,R2> Either<L2,R2> |
biMap(Fn1<? super L,? extends L2> leftFn,
Fn1<? super R,? extends R2> rightFn)
Dually map covariantly over both the left and right parameters.
|
<L2> Either<L2,R> |
biMapL(Fn1<? super L,? extends L2> fn)
Covariantly map over the left parameter.
|
<R2> Either<L,R2> |
biMapR(Fn1<? super R,? extends R2> fn)
Covariantly map over the right parameter.
|
Either<L,R> |
catchError(Fn1<? super L,? extends Monad<R,Either<L,?>>> recoveryFn)
|
<R2> Either<L,R2> |
discardL(Applicative<R2,Either<L,?>> appB)
Sequence both this
Applicative and appB , discarding this Applicative's
result and returning appB . |
<R2> Either<L,R> |
discardR(Applicative<R2,Either<L,?>> appB)
Sequence both this
Applicative and appB , discarding appB's result and
returning this Applicative . |
<C> Choice3<L,R,C> |
diverge()
Diverge this coproduct by introducing another possible type that it could represent.
|
Either<L,R> |
filter(Fn1<? super R,? extends Boolean> pred,
Fn0<L> leftFn0)
If this is a right value, apply
pred to it. |
Either<L,R> |
filter(Fn1<? super R,? extends Boolean> pred,
Fn1<? super R,? extends L> leftFn)
If this is a right value, apply
pred to it. |
<R2> Either<L,R2> |
flatMap(Fn1<? super R,? extends Monad<R2,Either<L,?>>> rightFn)
If a right value, unwrap it and apply it to
rightFn , returning the resulting
Either<L ,R> . |
<R2> Either<L,R2> |
fmap(Fn1<? super R,? extends R2> fn)
Covariantly transmute this functor's parameter using the given mapping function.
|
L |
forfeit(Fn1<? super R,? extends L> forfeitFn)
Inverse of recover.
|
static <L,R> Either<L,R> |
fromMaybe(Maybe<R> maybe,
Fn0<L> leftFn0)
Convert a
Maybe <R> into an Either<L, R> , supplying the left value from
leftFn in the case of Maybe.nothing() . |
Either<R,L> |
invert()
Swap the type parameters.
|
<R2> Lazy<Either<L,R2>> |
lazyZip(Lazy<? extends Applicative<Fn1<? super R,? extends R2>,Either<L,?>>> lazyAppFn)
Given a
lazy instance of this applicative over a mapping function, "zip" the two instances together
using whatever application semantics the current applicative supports. |
static <L,R> Either<L,R> |
left(L l)
Static factory method for creating a left value.
|
abstract <V> V |
match(Fn1<? super L,? extends V> leftFn,
Fn1<? super R,? extends V> rightFn)
Given two mapping functions (one from an
L to a V , one from an R to a
V ), unwrap the value stored in this Either , apply the appropriate mapping function,
and return the result. |
Either<L,R> |
merge(Fn2<? super L,? super L,? extends L> leftFn,
Fn2<? super R,? super R,? extends R> rightFn,
Either<L,R>... others)
Given two binary operators over L and R, merge multiple
Either<L, R> s into a single
Either<L, R> . |
R |
or(R defaultValue)
Return the value wrapped by this
Either if it's a right value; otherwise, return defaultValue. |
<T extends Throwable> |
orThrow(Fn1<? super L,? extends T> throwableFn)
Return the wrapped value if this is a right; otherwise, map the wrapped left value to a
T and throw
it. |
Either<L,R> |
peek(Fn1<? super L,? extends IO<?>> leftEffect,
Fn1<? super R,? extends IO<?>> rightEffect)
|
Either<L,R> |
peek(Fn1<? super R,? extends IO<?>> effect)
|
<R2> Either<L,R2> |
pure(R2 r2)
Lift the value
b into this applicative functor. |
static <L> Pure<Either<L,?>> |
pureEither()
|
R |
recover(Fn1<? super L,? extends R> recoveryFn)
"Recover" from a left value by applying a recoveryFn to the wrapped value and returning it in the case of a left
value; otherwise, return the wrapped right value.
|
static <L,R> Either<L,R> |
right(R r)
Static factory method for creating a right value.
|
Either<L,R> |
throwError(L l)
Throw an error value of type
E into the monad . |
Maybe<R> |
toMaybe()
In the left case, returns a
Maybe.nothing() ; otherwise, returns Maybe.maybe(A) around the right
value. |
<B> Either<L,B> |
trampolineM(Fn1<? super R,? extends MonadRec<RecursiveResult<R,B>,Either<L,?>>> fn)
Given some operation yielding a
RecursiveResult inside this MonadRec , internally trampoline the
operation until it yields a termination instruction. |
<R2,App extends Applicative<?,App>,TravB extends Traversable<R2,Either<L,?>>,AppTrav extends Applicative<TravB,App>> |
traverse(Fn1<? super R,? extends Applicative<R2,App>> fn,
Fn1<? super TravB,? extends AppTrav> pure)
Apply
fn to each element of this traversable from left to right, and collapse the results into
a single resulting applicative, potentially with the assistance of the applicative's pure function. |
static <R> Either<Throwable,R> |
trying(Fn0<? extends R> fn0)
Attempt to execute the
Fn0 , returning its result in a right value. |
static <L,R> Either<L,R> |
trying(Fn0<? extends R> fn0,
Fn1<? super Throwable,? extends L> leftFn)
Attempt to execute the
Fn0 , returning its result in a right value. |
static Either<Throwable,Unit> |
trying(SideEffect sideEffect)
Attempt to execute the
SideEffect , returning Unit in a right value. |
static <L> Either<L,Unit> |
trying(SideEffect sideEffect,
Fn1<? super Throwable,? extends L> leftFn)
Attempt to execute the
SideEffect , returning Unit in a right value. |
<R2> Either<L,R2> |
zip(Applicative<Fn1<? super R,? extends R2>,Either<L,?>> appFn)
Given another instance of this applicative over a mapping function, "zip" the two instances together using
whatever application semantics the current applicative supports.
|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
embed, project, projectA, projectB
public final R or(R defaultValue)
Either
if it's a right value; otherwise, return defaultValue.defaultValue
- the value to return if this is a leftpublic final R recover(Fn1<? super L,? extends R> recoveryFn)
recoveryFn
- a function from L to Rpublic final L forfeit(Fn1<? super R,? extends L> forfeitFn)
forfeitFn
and return it;
otherwise, return the wrapped left value.forfeitFn
- a function from R to Lpublic final <T extends Throwable> R orThrow(Fn1<? super L,? extends T> throwableFn) throws T extends Throwable
T
and throw
it.T
- the left parameter type (the throwable type)throwableFn
- a function from L to TT
- the result of applying the wrapped left value to throwableFn, if this is a leftT extends Throwable
public final Either<L,R> filter(Fn1<? super R,? extends Boolean> pred, Fn0<L> leftFn0)
pred
to it. If the result is true
, return the same
value; otherwise, return the result of leftSupplier
wrapped as a left value.
If this is a left value, return it.
pred
- the predicate to apply to a right valueleftFn0
- the supplier of a left value if pred failspublic final Either<L,R> filter(Fn1<? super R,? extends Boolean> pred, Fn1<? super R,? extends L> leftFn)
pred
to it. If the result is true
, return the same
value; otherwise, return the results of applying the right value to leftFn
wrapped as a left value.pred
- the predicate to apply to a right valueleftFn
- the function from the right value to a left value if pred failspublic <R2> Either<L,R2> flatMap(Fn1<? super R,? extends Monad<R2,Either<L,?>>> rightFn)
rightFn
, returning the resulting
Either<L ,R>
. Otherwise, return the left value.
Note that because this monadic form of flatMap
only supports mapping over a theoretical right value,
the resulting Either
must be invariant on the same left value to flatten properly.
flatMap
in interface Monad<R,Either<L,?>>
flatMap
in interface MonadError<L,R,Either<L,?>>
flatMap
in interface MonadRec<R,Either<L,?>>
R2
- the new right parameter typerightFn
- the function to apply to a right valuepublic <B> Either<L,B> trampolineM(Fn1<? super R,? extends MonadRec<RecursiveResult<R,B>,Either<L,?>>> fn)
RecursiveResult
inside this MonadRec
, internally trampoline the
operation until it yields a termination
instruction.
Stack-safety depends on implementations guaranteeing that the growth of the call stack is a constant factor independent of the number of invocations of the operation. For various examples of how this can be achieved in stereotypical circumstances, see the referenced types.
trampolineM
in interface MonadRec<R,Either<L,?>>
B
- the ultimate resulting carrier typefn
- the function to internally trampolineMonadRec
for a basic implementation
,
for a {@link CoProduct2 coproduct} implementation
,
for an implementation leveraging an already stack-safe {@link Monad#flatMap(Fn1)}
,
for a {@link MonadT monad transformer} implementation
public final Either<R,L> invert()
CoProduct2
@SafeVarargs public final Either<L,R> merge(Fn2<? super L,? super L,? extends L> leftFn, Fn2<? super R,? super R,? extends R> rightFn, Either<L,R>... others)
Either<L, R>
s into a single
Either<L, R>
. Note that merge
biases towards left values; that is, if any left
value exists, the result will be a left value, such that only unanimous right values result in an ultimate right
value.leftFn
- the binary operator for LrightFn
- the binary operator for Rothers
- the other Eithers to merge into this one@Deprecated public Either<L,R> peek(Fn1<? super R,? extends IO<?>> effect)
Either
unaltered.effect
- the effecting consumer@Deprecated public Either<L,R> peek(Fn1<? super L,? extends IO<?>> leftEffect, Fn1<? super R,? extends IO<?>> rightEffect)
Either
unaltered.leftEffect
- the effecting consumer for left valuesrightEffect
- the effecting consumer for right valuespublic abstract <V> V match(Fn1<? super L,? extends V> leftFn, Fn1<? super R,? extends V> rightFn)
L
to a V
, one from an R
to a
V
), unwrap the value stored in this Either
, apply the appropriate mapping function,
and return the result.public <C> Choice3<L,R,C> diverge()
CoProduct3<String, Integer,
Boolean>
is expected, a CoProduct2<String, Integer>
should suffice.
Generally, we use inheritance to make this a non-issue; however, with coproducts of differing magnitudes, we
cannot guarantee variance compatibility in one direction conveniently at construction time, and in the other
direction, at all. A CoProduct2
could not be a CoProduct3
without specifying all type parameters
that are possible for a CoProduct3
- more specifically, the third possible type - which is not
necessarily known at construction time, or even useful if never used in the context of a CoProduct3
. The
inverse inheritance relationship - CoProduct3
< CoProduct2
- is inherently unsound, as a
CoProduct3
cannot correctly implement CoProduct2.match(com.jnape.palatable.lambda.functions.Fn1<? super A, ? extends R>, com.jnape.palatable.lambda.functions.Fn1<? super B, ? extends R>)
, given that the third type C
is always possible.
For this reason, there is a diverge
method supported between all CoProduct
types of
single magnitude difference.
diverge
in interface CoProduct2<L,R,Either<L,R>>
C
- the additional possible type of this coproductCoProduct3
<A, B, C>public final <R2> Either<L,R2> fmap(Fn1<? super R,? extends R2> fn)
fmap
in interface Applicative<R,Either<L,?>>
fmap
in interface Functor<R,Either<L,?>>
fmap
in interface Monad<R,Either<L,?>>
fmap
in interface MonadError<L,R,Either<L,?>>
fmap
in interface MonadRec<R,Either<L,?>>
fmap
in interface Traversable<R,Either<L,?>>
R2
- the new parameter typefn
- the mapping functionpublic final <L2> Either<L2,R> biMapL(Fn1<? super L,? extends L2> fn)
biMapL
in interface Bifunctor<L,R,Either<?,?>>
biMapL
in interface BoundedBifunctor<L,R,Object,Object,Either<?,?>>
L2
- the new left parameter typefn
- the mapping functionpublic final <R2> Either<L,R2> biMapR(Fn1<? super R,? extends R2> fn)
biMapR(f) == fmap(f)
.biMapR
in interface Bifunctor<L,R,Either<?,?>>
biMapR
in interface BoundedBifunctor<L,R,Object,Object,Either<?,?>>
R2
- the new right parameter typefn
- the mapping functionpublic final <L2,R2> Either<L2,R2> biMap(Fn1<? super L,? extends L2> leftFn, Fn1<? super R,? extends R2> rightFn)
biMapL(lFn).biMapR(rFn)
.biMap
in interface Bifunctor<L,R,Either<?,?>>
biMap
in interface BoundedBifunctor<L,R,Object,Object,Either<?,?>>
L2
- the new left parameter typeR2
- the new right parameter typeleftFn
- the left parameter mapping functionrightFn
- the right parameter mapping functionpublic final <R2> Either<L,R2> pure(R2 r2)
b
into this applicative functor.pure
in interface Applicative<R,Either<L,?>>
pure
in interface Monad<R,Either<L,?>>
pure
in interface MonadError<L,R,Either<L,?>>
pure
in interface MonadRec<R,Either<L,?>>
R2
- the type of the returned applicative's parameterr2
- the valuepublic final <R2> Either<L,R2> zip(Applicative<Fn1<? super R,? extends R2>,Either<L,?>> appFn)
zip
in interface Applicative<R,Either<L,?>>
zip
in interface Monad<R,Either<L,?>>
zip
in interface MonadError<L,R,Either<L,?>>
zip
in interface MonadRec<R,Either<L,?>>
R2
- the resulting applicative parameter typeappFn
- the other applicative instancepublic <R2> Lazy<Either<L,R2>> lazyZip(Lazy<? extends Applicative<Fn1<? super R,? extends R2>,Either<L,?>>> lazyAppFn)
lazy
instance of this applicative over a mapping function, "zip" the two instances together
using whatever application semantics the current applicative supports. This is useful for applicatives that
support lazy evaluation and early termination.lazyZip
in interface Applicative<R,Either<L,?>>
lazyZip
in interface Monad<R,Either<L,?>>
lazyZip
in interface MonadError<L,R,Either<L,?>>
lazyZip
in interface MonadRec<R,Either<L,?>>
R2
- the resulting applicative parameter typelazyAppFn
- the lazy other applicative instanceMaybe
,
Either
public final <R2> Either<L,R2> discardL(Applicative<R2,Either<L,?>> appB)
Applicative
and appB
, discarding this Applicative's
result and returning appB
. This is generally useful for sequentially performing side-effects.discardL
in interface Applicative<R,Either<L,?>>
discardL
in interface Monad<R,Either<L,?>>
discardL
in interface MonadError<L,R,Either<L,?>>
discardL
in interface MonadRec<R,Either<L,?>>
R2
- the type of the returned Applicative's parameterappB
- the other Applicativepublic final <R2> Either<L,R> discardR(Applicative<R2,Either<L,?>> appB)
Applicative
and appB
, discarding appB's
result and
returning this Applicative
. This is generally useful for sequentially performing side-effects.discardR
in interface Applicative<R,Either<L,?>>
discardR
in interface Monad<R,Either<L,?>>
discardR
in interface MonadError<L,R,Either<L,?>>
discardR
in interface MonadRec<R,Either<L,?>>
R2
- the type of appB's parameterappB
- the other Applicativepublic Either<L,R> throwError(L l)
E
into the monad
.throwError
in interface MonadError<L,R,Either<L,?>>
l
- the error typemonad
public Either<L,R> catchError(Fn1<? super L,? extends Monad<R,Either<L,?>>> recoveryFn)
catchError
in interface MonadError<L,R,Either<L,?>>
recoveryFn
- the catch functionMonad
public final <R2,App extends Applicative<?,App>,TravB extends Traversable<R2,Either<L,?>>,AppTrav extends Applicative<TravB,App>> AppTrav traverse(Fn1<? super R,? extends Applicative<R2,App>> fn, Fn1<? super TravB,? extends AppTrav> pure)
fn
to each element of this traversable from left to right, and collapse the results into
a single resulting applicative, potentially with the assistance of the applicative's pure function.traverse
in interface Traversable<R,Either<L,?>>
R2
- the resulting element typeApp
- the result applicative typeTravB
- this Traversable instance over BAppTrav
- the full inferred resulting type from the traversalfn
- the function to applypure
- the applicative pure functionpublic final Maybe<R> toMaybe()
Maybe.nothing()
; otherwise, returns Maybe.maybe(A)
around the right
value.public static <L,R> Either<L,R> fromMaybe(Maybe<R> maybe, Fn0<L> leftFn0)
Maybe
<R> into an Either<L, R>
, supplying the left value from
leftFn
in the case of Maybe.nothing()
.L
- the left parameter typeR
- the right parameter typemaybe
- the maybeleftFn0
- the supplier to use for left valuespublic static <L,R> Either<L,R> trying(Fn0<? extends R> fn0, Fn1<? super Throwable,? extends L> leftFn)
Fn0
, returning its result in a right value. If the supplier throws an
exception, apply leftFn to it, wrap it in a left value and return it.L
- the left parameter typeR
- the right parameter typefn0
- the supplier of the right valueleftFn
- a function mapping E to Lpublic static <R> Either<Throwable,R> trying(Fn0<? extends R> fn0)
Fn0
, returning its result in a right value. If the supplier throws an
exception, wrap it in a left value and return it.R
- the right parameter typefn0
- the supplier of the right valuepublic static <L> Either<L,Unit> trying(SideEffect sideEffect, Fn1<? super Throwable,? extends L> leftFn)
SideEffect
, returning Unit
in a right value. If the runnable throws
an exception, apply leftFn
to it, wrap it in a left value, and return it.L
- the left parameter typesideEffect
- the runnableleftFn
- a function mapping E to LUnit
as a right value, or leftFn's mapping result as a left valuepublic static Either<Throwable,Unit> trying(SideEffect sideEffect)
SideEffect
, returning Unit
in a right value. If the runnable throws
exception, wrap it in a left value and return it.sideEffect
- the runnableUnit
as a right value, or a left value of the thrown exceptionpublic static <L,R> Either<L,R> left(L l)
L
- the left parameter typeR
- the right parameter typel
- the wrapped valuepublic static <L,R> Either<L,R> right(R r)
L
- the left parameter typeR
- the right parameter typer
- the wrapped value