Class Either<L,R>
- Type Parameters:
L
- The left parameter typeR
- The right parameter type
- All Implemented Interfaces:
CoProduct2<L,
,R, Either<L, R>> Applicative<R,
,Either<L, ?>> Bifunctor<L,
,R, Either<?, ?>> BoundedBifunctor<L,
,R, Object, Object, Either<?, ?>> Functor<R,
,Either<L, ?>> Monad<R,
,Either<L, ?>> MonadError<L,
,R, Either<L, ?>> MonadRec<R,
,Either<L, ?>> Traversable<R,
Either<L, ?>>
- Direct Known Subclasses:
Either.Left
,Either.Right
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.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final class
private static final class
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionfinal <L2,
R2> Either <L2, R2> Dually map covariantly over both the left and right parameters.Covariantly map over the left parameter.Covariantly map over the right parameter.discardL
(Applicative<R2, Either<L, ?>> appB) Sequence both thisApplicative
andappB
, discarding thisApplicative's
result and returningappB
.discardR
(Applicative<R2, Either<L, ?>> appB) Sequence both thisApplicative
andappB
, discardingappB's
result and returning thisApplicative
.diverge()
Diverge this coproduct by introducing another possible type that it could represent.If this is a right value, applypred
to it.If this is a right value, applypred
to it.If a right value, unwrap it and apply it torightFn
, returning the resultingEither<L ,R>
.Covariantly transmute this functor's parameter using the given mapping function.final L
Inverse of recover.static <L,
R> Either <L, R> Convert aMaybe
<R> into anEither<L, R>
, supplying the left value fromleftFn
in the case ofMaybe.nothing()
.invert()
Swap the type parameters.Given alazy
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
Given two mapping functions (one from anL
to aV
, one from anR
to aV
), unwrap the value stored in thisEither
, apply the appropriate mapping function, and return the result.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 multipleEither<L, R>
s into a singleEither<L, R>
.final R
Return the value wrapped by thisEither
if it's a right value; otherwise, return defaultValue.Return the wrapped value if this is a right; otherwise, map the wrapped left value to aT
and throw it.Deprecated.pure
(R2 r2) Lift the valueb
into this applicative functor.final R
"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.throwError
(L l) Throw an error value of typeE
into themonad
.toMaybe()
In the left case, returns aMaybe.nothing()
; otherwise, returnsMaybe.maybe(A)
around the right value.trampolineM
(Fn1<? super R, ? extends MonadRec<RecursiveResult<R, B>, Either<L, ?>>> fn) Given some operation yielding aRecursiveResult
inside thisMonadRec
, internally trampoline the operation until it yields atermination
instruction.final <R2,
App extends Applicative<?, App>, TravB extends Traversable<R2, Either<L, ?>>, AppTrav extends Applicative<TravB, App>>
AppTravtraverse
(Fn1<? super R, ? extends Applicative<R2, App>> fn, Fn1<? super TravB, ? extends AppTrav> pure) Applyfn
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.Attempt to execute theFn0
, returning its result in a right value.static <L,
R> Either <L, R> Attempt to execute theFn0
, returning its result in a right value.trying
(SideEffect sideEffect) Attempt to execute theSideEffect
, returningUnit
in a right value.trying
(SideEffect sideEffect, Fn1<? super Throwable, ? extends L> leftFn) Attempt to execute theSideEffect
, returningUnit
in a right value.Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface com.jnape.palatable.lambda.adt.coproduct.CoProduct2
embed, project, projectA, projectB
-
Constructor Details
-
Either
private Either()
-
-
Method Details
-
or
Return the value wrapped by thisEither
if it's a right value; otherwise, return defaultValue.- Parameters:
defaultValue
- the value to return if this is a left- Returns:
- the value wrapped by this Either if right; otherwise, defaultValue
-
recover
"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.- Parameters:
recoveryFn
- a function from L to R- Returns:
- either the wrapped value (if right) or the result of the left value applied to recoveryFn
-
forfeit
Inverse of recover. If this is a right value, apply the wrapped value toforfeitFn
and return it; otherwise, return the wrapped left value.- Parameters:
forfeitFn
- a function from R to L- Returns:
- either the wrapped value (if left) or the result of the right value applied to forfeitFn
-
orThrow
Return the wrapped value if this is a right; otherwise, map the wrapped left value to aT
and throw it.- Type Parameters:
T
- the left parameter type (the throwable type)- Parameters:
throwableFn
- a function from L to T- Returns:
- the wrapped value if this is a right
- Throws:
T
- the result of applying the wrapped left value to throwableFn, if this is a left
-
filter
If this is a right value, applypred
to it. If the result istrue
, return the same value; otherwise, return the result ofleftSupplier
wrapped as a left value.If this is a left value, return it.
- Parameters:
pred
- the predicate to apply to a right valueleftFn0
- the supplier of a left value if pred fails- Returns:
- this if a left value or a right value that pred matches; otherwise, the result of leftSupplier wrapped in a left
-
filter
public final Either<L,R> filter(Fn1<? super R, ? extends Boolean> pred, Fn1<? super R, ? extends L> leftFn) If this is a right value, applypred
to it. If the result istrue
, return the same value; otherwise, return the results of applying the right value toleftFn
wrapped as a left value.- Parameters:
pred
- the predicate to apply to a right valueleftFn
- the function from the right value to a left value if pred fails- Returns:
- this is a left value or a right value that pred matches; otherwise, the result of leftFn applied to the right value, wrapped in a left
-
flatMap
If a right value, unwrap it and apply it torightFn
, returning the resultingEither<L ,R>
. Otherwise, return the left value.Note that because this monadic form of
flatMap
only supports mapping over a theoretical right value, the resultingEither
must be invariant on the same left value to flatten properly.- Specified by:
flatMap
in interfaceMonad<L,
R> - Specified by:
flatMap
in interfaceMonadError<L,
R, Either<L, ?>> - Specified by:
flatMap
in interfaceMonadRec<L,
R> - Type Parameters:
R2
- the new right parameter type- Parameters:
rightFn
- the function to apply to a right value- Returns:
- the Either resulting from applying rightFn to this right value, or this left value if left
-
trampolineM
public <B> Either<L,B> trampolineM(Fn1<? super R, ? extends MonadRec<RecursiveResult<R, B>, Either<L, ?>>> fn) Given some operation yielding aRecursiveResult
inside thisMonadRec
, internally trampoline the operation until it yields atermination
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.
- Specified by:
trampolineM
in interfaceMonadRec<L,
R> - Type Parameters:
B
- the ultimate resulting carrier type- Parameters:
fn
- the function to internally trampoline- Returns:
- the trampolined
MonadRec
- See Also:
-
invert
Description copied from interface:CoProduct2
Swap the type parameters. -
merge
@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) Given two binary operators over L and R, merge multipleEither<L, R>
s into a singleEither<L, R>
. Note thatmerge
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.- Parameters:
leftFn
- the binary operator for LrightFn
- the binary operator for Rothers
- the other Eithers to merge into this one- Returns:
- the merged Either
-
peek
Perform side-effects against a wrapped right value, returning back theEither
unaltered.- Parameters:
effect
- the effecting consumer- Returns:
- the Either, unaltered
-
peek
@Deprecated public Either<L,R> peek(Fn1<? super L, ? extends IO<?>> leftEffect, Fn1<? super R, ? extends IO<?>> rightEffect) Perform side-effects against a wrapped right or left value, returning back theEither
unaltered.- Parameters:
leftEffect
- the effecting consumer for left valuesrightEffect
- the effecting consumer for right values- Returns:
- the Either, unaltered
-
match
Given two mapping functions (one from anL
to aV
, one from anR
to aV
), unwrap the value stored in thisEither
, apply the appropriate mapping function, and return the result. -
diverge
Diverge this coproduct by introducing another possible type that it could represent. As no morphisms can be provided mapping current types to the new type, this operation merely acts as a convenience method to allow the use of a more convergent coproduct with a more divergent one; that is, if aCoProduct3<String, Integer, Boolean>
is expected, aCoProduct2<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 aCoProduct3
without specifying all type parameters that are possible for aCoProduct3
- more specifically, the third possible type - which is not necessarily known at construction time, or even useful if never used in the context of aCoProduct3
. The inverse inheritance relationship -CoProduct3
<CoProduct2
- is inherently unsound, as aCoProduct3
cannot correctly implementCoProduct2.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 typeC
is always possible.For this reason, there is a
diverge
method supported between allCoProduct
types of single magnitude difference.- Specified by:
diverge
in interfaceCoProduct2<L,
R, Either<L, R>> - Type Parameters:
C
- the additional possible type of this coproduct- Returns:
- a
CoProduct3
<A, B, C>
-
fmap
Covariantly transmute this functor's parameter using the given mapping function. Generally this method is specialized to return an instance of the class implementing Functor.- Specified by:
fmap
in interfaceApplicative<L,
R> - Specified by:
fmap
in interfaceFunctor<L,
R> - Specified by:
fmap
in interfaceMonad<L,
R> - Specified by:
fmap
in interfaceMonadError<L,
R, Either<L, ?>> - Specified by:
fmap
in interfaceMonadRec<L,
R> - Specified by:
fmap
in interfaceTraversable<L,
R> - Type Parameters:
R2
- the new parameter type- Parameters:
fn
- the mapping function- Returns:
- a functor over B (the new parameter type)
-
biMapL
Covariantly map over the left parameter.- Specified by:
biMapL
in interfaceBifunctor<L,
R, Either<?, ?>> - Specified by:
biMapL
in interfaceBoundedBifunctor<L,
R, Object, Object, Either<?, ?>> - Type Parameters:
L2
- the new left parameter type- Parameters:
fn
- the mapping function- Returns:
- a bifunctor over C (the new left parameter) and B (the same right parameter)
-
biMapR
Covariantly map over the right parameter. For all bifunctors that are also functors, it should hold thatbiMapR(f) == fmap(f)
.- Specified by:
biMapR
in interfaceBifunctor<L,
R, Either<?, ?>> - Specified by:
biMapR
in interfaceBoundedBifunctor<L,
R, Object, Object, Either<?, ?>> - Type Parameters:
R2
- the new right parameter type- Parameters:
fn
- the mapping function- Returns:
- a bifunctor over A (the same left parameter) and C (the new right parameter)
-
biMap
public final <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. This is isomorphic tobiMapL(lFn).biMapR(rFn)
.- Specified by:
biMap
in interfaceBifunctor<L,
R, Either<?, ?>> - Specified by:
biMap
in interfaceBoundedBifunctor<L,
R, Object, Object, Either<?, ?>> - Type Parameters:
L2
- the new left parameter typeR2
- the new right parameter type- Parameters:
leftFn
- the left parameter mapping functionrightFn
- the right parameter mapping function- Returns:
- a bifunctor over C (the new left parameter type) and D (the new right parameter type)
-
pure
Lift the valueb
into this applicative functor.- Specified by:
pure
in interfaceApplicative<L,
R> - Specified by:
pure
in interfaceMonad<L,
R> - Specified by:
pure
in interfaceMonadError<L,
R, Either<L, ?>> - Specified by:
pure
in interfaceMonadRec<L,
R> - Type Parameters:
R2
- the type of the returned applicative's parameter- Parameters:
r2
- the value- Returns:
- an instance of this applicative over b
-
zip
Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.- Specified by:
zip
in interfaceApplicative<L,
R> - Specified by:
zip
in interfaceMonad<L,
R> - Specified by:
zip
in interfaceMonadError<L,
R, Either<L, ?>> - Specified by:
zip
in interfaceMonadRec<L,
R> - Type Parameters:
R2
- the resulting applicative parameter type- Parameters:
appFn
- the other applicative instance- Returns:
- the mapped applicative
-
lazyZip
public <R2> Lazy<Either<L,R2>> lazyZip(Lazy<? extends Applicative<Fn1<? super R, ? extends R2>, Either<L, ?>>> lazyAppFn) Given alazy
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.- Specified by:
lazyZip
in interfaceApplicative<L,
R> - Specified by:
lazyZip
in interfaceMonad<L,
R> - Specified by:
lazyZip
in interfaceMonadError<L,
R, Either<L, ?>> - Specified by:
lazyZip
in interfaceMonadRec<L,
R> - Type Parameters:
R2
- the resulting applicative parameter type- Parameters:
lazyAppFn
- the lazy other applicative instance- Returns:
- the mapped applicative
- See Also:
-
discardL
Sequence both thisApplicative
andappB
, discarding thisApplicative's
result and returningappB
. This is generally useful for sequentially performing side-effects.- Specified by:
discardL
in interfaceApplicative<L,
R> - Specified by:
discardL
in interfaceMonad<L,
R> - Specified by:
discardL
in interfaceMonadError<L,
R, Either<L, ?>> - Specified by:
discardL
in interfaceMonadRec<L,
R> - Type Parameters:
R2
- the type of the returned Applicative's parameter- Parameters:
appB
- the other Applicative- Returns:
- appB
-
discardR
Sequence both thisApplicative
andappB
, discardingappB's
result and returning thisApplicative
. This is generally useful for sequentially performing side-effects.- Specified by:
discardR
in interfaceApplicative<L,
R> - Specified by:
discardR
in interfaceMonad<L,
R> - Specified by:
discardR
in interfaceMonadError<L,
R, Either<L, ?>> - Specified by:
discardR
in interfaceMonadRec<L,
R> - Type Parameters:
R2
- the type of appB's parameter- Parameters:
appB
- the other Applicative- Returns:
- this Applicative
-
throwError
Throw an error value of typeE
into themonad
.- Specified by:
throwError
in interfaceMonadError<L,
R, Either<L, ?>> - Parameters:
l
- the error type- Returns:
- the
monad
-
catchError
- Specified by:
catchError
in interfaceMonadError<L,
R, Either<L, ?>> - Parameters:
recoveryFn
- the catch function- Returns:
- the recovered
Monad
-
traverse
public final <R2,App extends Applicative<?, AppTrav traverseApp>, TravB extends Traversable<R2, Either<L, ?>>, AppTrav extends Applicative<TravB, App>> (Fn1<? super R, ? extends Applicative<R2, App>> fn, Fn1<? super TravB, ? extends AppTrav> pure) Applyfn
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.- Specified by:
traverse
in interfaceTraversable<L,
R> - Type Parameters:
R2
- the resulting element typeApp
- the result applicative typeTravB
- this Traversable instance over BAppTrav
- the full inferred resulting type from the traversal- Parameters:
fn
- the function to applypure
- the applicative pure function- Returns:
- the traversed Traversable, wrapped inside an applicative
-
toMaybe
In the left case, returns aMaybe.nothing()
; otherwise, returnsMaybe.maybe(A)
around the right value.- Returns:
- Maybe the right value
-
fromMaybe
Convert aMaybe
<R> into anEither<L, R>
, supplying the left value fromleftFn
in the case ofMaybe.nothing()
.- Type Parameters:
L
- the left parameter typeR
- the right parameter type- Parameters:
maybe
- the maybeleftFn0
- the supplier to use for left values- Returns:
- a right value of the contained maybe value, or a left value of leftFn's result
-
trying
public static <L,R> Either<L,R> trying(Fn0<? extends R> fn0, Fn1<? super Throwable, ? extends L> leftFn) Attempt to execute theFn0
, 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.- Type Parameters:
L
- the left parameter typeR
- the right parameter type- Parameters:
fn0
- the supplier of the right valueleftFn
- a function mapping E to L- Returns:
- the supplier result as a right value, or leftFn's mapping result as a left value
-
trying
Attempt to execute theFn0
, returning its result in a right value. If the supplier throws an exception, wrap it in a left value and return it.- Type Parameters:
R
- the right parameter type- Parameters:
fn0
- the supplier of the right value- Returns:
- the supplier result as a right value, or a left value of the thrown exception
-
trying
public static <L> Either<L,Unit> trying(SideEffect sideEffect, Fn1<? super Throwable, ? extends L> leftFn) Attempt to execute theSideEffect
, returningUnit
in a right value. If the runnable throws an exception, applyleftFn
to it, wrap it in a left value, and return it.- Type Parameters:
L
- the left parameter type- Parameters:
sideEffect
- the runnableleftFn
- a function mapping E to L- Returns:
Unit
as a right value, or leftFn's mapping result as a left value
-
trying
Attempt to execute theSideEffect
, returningUnit
in a right value. If the runnable throws exception, wrap it in a left value and return it.- Parameters:
sideEffect
- the runnable- Returns:
Unit
as a right value, or a left value of the thrown exception
-
left
Static factory method for creating a left value.- Type Parameters:
L
- the left parameter typeR
- the right parameter type- Parameters:
l
- the wrapped value- Returns:
- a left value of l
-
right
Static factory method for creating a right value.- Type Parameters:
L
- the left parameter typeR
- the right parameter type- Parameters:
r
- the wrapped value- Returns:
- a right value of r
-
pureEither
- Type Parameters:
L
- the left type- Returns:
- the
Pure
instance
-
matching
into anIO
and explicitly running it