Skip to content

Commit 3bce5e0

Browse files
Fixes #414. Add fj.data.Either.leftMap, rightMap.
Also adds LeftProjection.traverseP1, RightProjection.valueE(String), RightProjection.orValue.
1 parent d83e6fe commit 3bce5e0

File tree

2 files changed

+739
-15
lines changed

2 files changed

+739
-15
lines changed

core/src/main/java/fj/data/Either.java

Lines changed: 86 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,16 @@
11
package fj.data;
22

3-
import fj.Equal;
4-
import fj.F;
5-
import fj.F0;
6-
import fj.Function;
7-
import fj.Hash;
8-
import fj.P1;
9-
import fj.Show;
10-
import fj.Unit;
3+
import fj.*;
114
import fj.function.Effect1;
125

13-
import java.util.Collection;
14-
import java.util.Iterator;
6+
import java.util.*;
157

168
import static fj.Bottom.error;
17-
import static fj.Function.compose;
18-
import static fj.Function.identity;
9+
import static fj.Function.*;
1910
import static fj.P.p;
2011
import static fj.Unit.unit;
2112
import static fj.data.Array.mkArray;
22-
import static fj.data.List.cons_;
23-
import static fj.data.List.list;
24-
import static fj.data.List.single;
13+
import static fj.data.List.*;
2514
import static fj.data.Option.some;
2615

2716
/**
@@ -321,6 +310,19 @@ public <C> IO<Either<C, B>> traverseIO(final F<A, IO<C>> f) {
321310
IOFunctions.unit(Either.right(e.right().value()));
322311
}
323312

313+
/**
314+
* Traverse this left with the given function and collect the output as a p1.
315+
*
316+
* @param f the given function
317+
* @param <C> the type of the p1 value
318+
* @return the p1
319+
*/
320+
public <C> P1<Either<C, B>> traverseP1(final F<A, P1<C>> f) {
321+
return e.isLeft() ?
322+
f.f(value()).map(left_()) :
323+
p(right(e.right().value()));
324+
}
325+
324326
/**
325327
* Returns <code>None</code> if this projection has no value or if the given predicate
326328
* <code>p</code> does not hold for the value, otherwise, returns a right in <code>Some</code>.
@@ -464,6 +466,16 @@ public Either<A, B> either() {
464466
return e;
465467
}
466468

469+
/**
470+
* Returns the value of this projection or fails with the given error message.
471+
*
472+
* @param err The error message to fail with.
473+
* @return The value of this projection
474+
*/
475+
public B valueE(final String err) {
476+
return valueE(p(err));
477+
}
478+
467479
/**
468480
* Returns the value of this projection or fails with the given error message.
469481
*
@@ -487,6 +499,16 @@ public B value() {
487499
return valueE(p("right.value on Left"));
488500
}
489501

502+
/**
503+
* The value of this projection or the given argument.
504+
*
505+
* @param a The value to return if this projection has no value.
506+
* @return The value of this projection or the given argument.
507+
*/
508+
public B orValue(final B a) {
509+
return e.isRight() ? value() : a;
510+
}
511+
490512
/**
491513
* The value of this projection or the given argument.
492514
*
@@ -586,12 +608,26 @@ public <C> IO<Either<A, C>> traverseIO(final F<B, IO<C>> f) {
586608
IOFunctions.lazy(() -> left(e.left().value()));
587609
}
588610

611+
/**
612+
* Traverse this right with the given function and collect the output as a p1.
613+
*
614+
* @param f the given function
615+
* @param <C> the type of the p1 value
616+
* @return the p1
617+
*/
589618
public <C> P1<Either<A, C>> traverseP1(final F<B, P1<C>> f) {
590619
return e.isRight() ?
591620
f.f(value()).map(right_()) :
592621
p(left(e.left().value()));
593622
}
594623

624+
/**
625+
* Traverse this right with the given function and collect the output as an option.
626+
*
627+
* @param f the given function
628+
* @param <C> the type of the option value
629+
* @return the option
630+
*/
595631
public <C> Option<Either<A, C>> traverseOption(final F<B, Option<C>> f) {
596632
return e.isRight() ?
597633
f.f(value()).map(right_()) :
@@ -758,13 +794,45 @@ public static <A, B, X> F<Either<A,B>, X> either_(final F<A, X> left, final F<B,
758794
}
759795

760796
/**
797+
* Map the given function across this either's left projection.
798+
*
799+
* @param f the given function
800+
* @param <X> the type of the function output
801+
* @return the either
802+
*/
803+
public final <X> Either<X, B> leftMap(final F<A, X> f) {
804+
return left().map(f);
805+
}
806+
807+
/**
808+
* Return a function that maps a given function across this either's left projection.
809+
*
810+
* @param <A> the type of the right value
811+
* @param <B> the type of the left value
812+
* @param <X> the type of the function output
761813
* @return A function that maps another function across an either's left projection.
762814
*/
763815
public static <A, B, X> F<F<A, X>, F<Either<A, B>, Either<X, B>>> leftMap_() {
764816
return axf -> e -> e.left().map(axf);
765817
}
766818

767819
/**
820+
* Map the given function across this either's right.
821+
*
822+
* @param f the given function
823+
* @param <X> the type of the function output
824+
* @return the either
825+
*/
826+
public final <X> Either<A, X> rightMap(final F<B, X> f) {
827+
return right().map(f);
828+
}
829+
830+
/**
831+
* Return a function that maps a given function across this either's right projection.
832+
*
833+
* @param <A> the type of the right value
834+
* @param <B> the type of the left value
835+
* @param <X> the type of the function output
768836
* @return A function that maps another function across an either's right projection.
769837
*/
770838
public static <A, B, X> F<F<B, X>, F<Either<A, B>, Either<A, X>>> rightMap_() {
@@ -796,6 +864,7 @@ public static <A, B> Either<A, B> joinRight(final Either<A, Either<A, B>> e) {
796864
*
797865
* @param a The list of values to sequence with the either monad.
798866
* @return A sequenced value.
867+
* @see fj.data.List#sequenceEitherLeft
799868
*/
800869
public static <A, X> Either<List<A>, X> sequenceLeft(final List<Either<A, X>> a) {
801870
return a.isEmpty() ?
@@ -808,6 +877,8 @@ public static <A, X> Either<List<A>, X> sequenceLeft(final List<Either<A, X>> a)
808877
*
809878
* @param a The list of values to sequence with the either monad.
810879
* @return A sequenced value.
880+
* @see fj.data.List#sequenceEither
881+
* @see fj.data.List#sequenceEitherRight
811882
*/
812883
public static <B, X> Either<X, List<B>> sequenceRight(final List<Either<X, B>> a) {
813884
return a.isEmpty() ?

0 commit comments

Comments
 (0)