11package fj .data ;
22
3- import static fj .Bottom .error ;
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 ;
11+ import fj .function .Effect1 ;
412
5- import fj .*;
13+ import java .util .Collection ;
14+ import java .util .Iterator ;
615
16+ import static fj .Bottom .error ;
17+ import static fj .Function .compose ;
718import static fj .Function .identity ;
819import static fj .P .p ;
9-
10- import fj .function .Effect1 ;
11-
1220import static fj .Unit .unit ;
1321import static fj .data .Array .mkArray ;
22+ import static fj .data .List .cons_ ;
1423import static fj .data .List .list ;
1524import static fj .data .List .single ;
16- import static fj .data .List .cons_ ;
1725import static fj .data .Option .some ;
1826
19- import java .util .Collection ;
20- import java .util .Iterator ;
21-
2227/**
2328 * The <code>Either</code> type represents a value of one of two possible types (a disjoint union).
2429 * The data constructors; <code>Left</code> and <code>Right</code> represent the two possible
@@ -72,11 +77,7 @@ public final RightProjection<A, B> right() {
7277 * @param right The function to call if this is right.
7378 * @return The reduced value.
7479 */
75- public final <X > X either (final F <A , X > left , final F <B , X > right ) {
76- return isLeft () ?
77- left .f (left ().value ()) :
78- right .f (right ().value ());
79- }
80+ public abstract <X > X either (final F <A , X > left , final F <B , X > right );
8081
8182 /**
8283 * Map the given functions across the appropriate side.
@@ -86,9 +87,7 @@ public final <X> X either(final F<A, X> left, final F<B, X> right) {
8687 * @return A new either value after mapping with the appropriate function applied.
8788 */
8889 public final <X , Y > Either <X , Y > bimap (final F <A , X > left , final F <B , Y > right ) {
89- return isLeft () ?
90- left (left .f (left ().value ())) :
91- right (right .f (right ().value ()));
90+ return either (compose (left_ (), left ), compose (right_ (), right ));
9291 }
9392
9493 @ Override
@@ -107,7 +106,7 @@ public final int hashCode() {
107106 * @return The value of this either swapped to the opposing side.
108107 */
109108 public final Either <B , A > swap () {
110- return isLeft () ? new Right <>((( Left < A , B >) this ). a ) : new Left <>((( Right < A , B >) this ). b );
109+ return either ( right_ (), left_ () );
111110 }
112111
113112 private static final class Left <A , B > extends Either <A , B > {
@@ -124,6 +123,11 @@ public boolean isLeft() {
124123 public boolean isRight () {
125124 return false ;
126125 }
126+
127+ @ Override
128+ public <X > X either (F <A , X > left , F <B , X > right ) {
129+ return left .f (a );
130+ }
127131 }
128132
129133 private static final class Right <A , B > extends Either <A , B > {
@@ -140,6 +144,11 @@ public boolean isLeft() {
140144 public boolean isRight () {
141145 return true ;
142146 }
147+
148+ @ Override
149+ public <X > X either (F <A , X > left , F <B , X > right ) {
150+ return right .f (b );
151+ }
143152 }
144153
145154 /**
@@ -414,17 +423,17 @@ public Collection<A> toCollection() {
414423 return toList ().toCollection ();
415424 }
416425
417- public <C > Option <Either <C ,B >> traverseOption (F <A , Option <C >> f ) {
426+ public <C > Option <Either <C ,B >> traverseOption (F <A , Option <C >> f ) {
418427 return e .isLeft () ?
419- f .f (value ()).map (Either ::< C , B > left ) :
420- some (Either . right (e .right ().value ()));
421- }
428+ f .f (value ()).map (left_ () ) :
429+ some (right (e .right ().value ()));
430+ }
422431
423- public <C > Stream <Either <C , B >> traverseStream (F <A , Stream <C >> f ) {
424- return e .isLeft () ?
425- f .f (value ()).map (Either ::< C , B > left ) :
426- Stream .single (Either . right (e .right ().value ()));
427- }
432+ public <C > Stream <Either <C , B >> traverseStream (F <A , Stream <C >> f ) {
433+ return e .isLeft () ?
434+ f .f (value ()).map (left_ () ) :
435+ Stream .single (right (e .right ().value ()));
436+ }
428437 }
429438
430439 /**
@@ -543,7 +552,6 @@ public <X> Either<A, X> bind(final F<B, Either<A, X>> f) {
543552 return e .isRight () ? f .f (value ()) : new Left <>(e .left ().value ());
544553 }
545554
546-
547555 /**
548556 * Anonymous bind through this projection.
549557 *
@@ -553,17 +561,18 @@ public <X> Either<A, X> bind(final F<B, Either<A, X>> f) {
553561 public <X > Either <A , X > sequence (final Either <A , X > e ) {
554562 return bind (Function .constant (e ));
555563 }
564+
556565 /**
557- * Traverse with function that produces List (non-determinism).
558- *
559- * @param f the function to traverse with
560- * @return An either after traversing through this projection.
561- */
562- public <C > List <Either <A , C >> traverseList (final F <B , List <C >> f ) {
563- return e .isRight () ?
564- f .f (value ()).map (Either :: right ) :
565- list (left (e .left ().value ()));
566- }
566+ * Traverse with function that produces List (non-determinism).
567+ *
568+ * @param f the function to traverse with
569+ * @return An either after traversing through this projection.
570+ */
571+ public <C > List <Either <A , C >> traverseList (final F <B , List <C >> f ) {
572+ return e .isRight () ?
573+ f .f (value ()).map (right_ () ) :
574+ list (left (e .left ().value ()));
575+ }
567576
568577 /**
569578 * Traverse with a function that has IO effect
@@ -573,19 +582,19 @@ public <C> List<Either<A, C>> traverseList(final F<B, List<C>> f) {
573582 */
574583 public <C > IO <Either <A , C >> traverseIO (final F <B , IO <C >> f ) {
575584 return e .isRight () ?
576- IOFunctions .map (f .f (value ()), Either ::< A , C > right ) :
585+ IOFunctions .map (f .f (value ()), right_ () ) :
577586 IOFunctions .lazy (() -> left (e .left ().value ()));
578587 }
579588
580589 public <C > P1 <Either <A , C >> traverseP1 (final F <B , P1 <C >> f ) {
581590 return e .isRight () ?
582- f .f (value ()).map (Either ::< A , C > right ) :
591+ f .f (value ()).map (right_ () ) :
583592 p (left (e .left ().value ()));
584593 }
585594
586595 public <C > Option <Either <A , C >> traverseOption (final F <B , Option <C >> f ) {
587596 return e .isRight () ?
588- f .f (value ()).map (Either ::< A , C > right ) :
597+ f .f (value ()).map (right_ () ) :
589598 some (left (e .left ().value ()));
590599 }
591600
@@ -758,8 +767,7 @@ public static <A, B, X> F<F<B, X>, F<Either<A, B>, Either<A, X>>> rightMap_() {
758767 * @return An either after joining.
759768 */
760769 public static <A , B > Either <A , B > joinLeft (final Either <Either <A , B >, B > e ) {
761- final F <Either <A , B >, Either <A , B >> id = identity ();
762- return e .left ().bind (id );
770+ return e .left ().bind (identity ());
763771 }
764772
765773 /**
@@ -769,8 +777,7 @@ public static <A, B> Either<A, B> joinLeft(final Either<Either<A, B>, B> e) {
769777 * @return An either after joining.
770778 */
771779 public static <A , B > Either <A , B > joinRight (final Either <A , Either <A , B >> e ) {
772- final F <Either <A , B >, Either <A , B >> id = identity ();
773- return e .right ().bind (id );
780+ return e .right ().bind (identity ());
774781 }
775782
776783 /**
@@ -781,7 +788,7 @@ public static <A, B> Either<A, B> joinRight(final Either<A, Either<A, B>> e) {
781788 */
782789 public static <A , X > Either <List <A >, X > sequenceLeft (final List <Either <A , X >> a ) {
783790 return a .isEmpty () ?
784- Either . left (List .nil ()) :
791+ left (List .nil ()) :
785792 a .head ().left ().bind (aa -> sequenceLeft (a .tail ()).left ().map (cons_ (aa )));
786793 }
787794
@@ -793,7 +800,7 @@ public static <A, X> Either<List<A>, X> sequenceLeft(final List<Either<A, X>> a)
793800 */
794801 public static <B , X > Either <X , List <B >> sequenceRight (final List <Either <X , B >> a ) {
795802 return a .isEmpty () ?
796- Either . right (List .nil ()) :
803+ right (List .nil ()) :
797804 a .head ().right ().bind (bb -> sequenceRight (a .tail ()).right ().map (cons_ (bb )));
798805 }
799806
@@ -807,10 +814,10 @@ public final <C> List<Either<A, C>> traverseListRight(final F<B, List<C>> f) {
807814 }
808815
809816 /**
810- * Traversable instance of LeftProjection of Either for List.
811- *
812- * @return traversed value
813- */
817+ * Traversable instance of LeftProjection of Either for List.
818+ *
819+ * @return traversed value
820+ */
814821 public final <C > List <Either <C , B >> traverseListLeft (final F <A , List <C >> f ) {
815822 return left ().traverseList (f );
816823 }
@@ -869,16 +876,14 @@ public final <C> Stream<Either<C, B>> traverseStreamLeft(final F<A, Stream<C>> f
869876 return left ().traverseStream (f );
870877 }
871878
872-
873-
874879 /**
875880 * Takes an <code>Either</code> to its contained value within left or right.
876881 *
877882 * @param e The either to reduce.
878883 * @return An <code>Either</code> to its contained value within left or right.
879884 */
880885 public static <A > A reduce (final Either <A , A > e ) {
881- return e .isLeft () ? e . left (). value () : e . right (). value ( );
886+ return e .either ( identity (), identity () );
882887 }
883888
884889 /**
0 commit comments