1 /*
2 Copyright 2011 Atlassian
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16 package io.atlassian.fugue;
17
18 import static io.atlassian.fugue.Option.none;
19 import static io.atlassian.fugue.Option.some;
20 import static io.atlassian.fugue.Suppliers.ofInstance;
21 import static java.util.Objects.requireNonNull;
22
23 import java.io.Serializable;
24 import java.util.Iterator;
25 import java.util.NoSuchElementException;
26 import java.util.Optional;
27 import java.util.function.Consumer;
28 import java.util.function.Function;
29 import java.util.function.Predicate;
30 import java.util.function.Supplier;
31 import java.util.stream.Stream;
32
33 /**
34 * A class that acts as a container for a value of one of two types. An Either
35 * will be either {@link Either.Left Left} or {@link Either.Right Right}.
36 * <p>
37 * Checking which type an Either is can be done by calling the @
38 * {@link #isLeft()} and {@link #isRight()} methods.
39 * <p>
40 * An Either can be used to express a success or failure case. By convention,
41 * Right is used to store the success value, (you can use the play on words
42 * "right" == "correct" as a mnemonic) and Left is used to store failure values
43 * (such as exceptions).
44 * <p>
45 * While this class is public and abstract it does not expose a constructor as
46 * only the concrete Left and Right subclasses are meant to be used.
47 * <p>
48 * Either is immutable, but does not force immutability on contained objects; if
49 * the contained objects are mutable then equals and hashcode methods should not
50 * be relied on.
51 * <p>
52 * Since 2.2, there have been some right-biased methods added. With 2.3 the
53 * available right-biased methods has increased. The purpose of these is that
54 * you can do something like {@code either.map(...)} directly, which is
55 * identical to calling {@code either.right().map(...)}.
56 *
57 * @since 1.0
58 */
59 public abstract class Either<L, R> implements Serializable {
60 private static final long serialVersionUID = -1L;
61
62 //
63 // factory methods
64 //
65
66 /**
67 * <p>
68 * left.
69 * </p>
70 *
71 * @param <L> the LHS type
72 * @param <R> the RHS type
73 * @param left the value to be stored, must not be null
74 * @return a Left containing the supplied value
75 * @since 1.0
76 */
77 public static <L, R> Either<L, R> left(final L left) {
78 requireNonNull(left);
79 return new Left<>(left);
80 }
81
82 /**
83 * <p>
84 * right.
85 * </p>
86 *
87 * @param <L> the LHS type
88 * @param <R> the RHS type
89 * @param right the value to be stored, must not be null
90 * @return a Right containing the supplied value
91 * @since 1.0
92 */
93 public static <L, R> Either<L, R> right(final R right) {
94 requireNonNull(right);
95 return new Right<>(right);
96 }
97
98 //
99 // constructors
100 //
101
102 Either() {}
103
104 //
105 // methods
106 //
107
108 /**
109 * Projects this either as a left.
110 *
111 * @return A left projection of this either.
112 */
113 public final LeftProjection left() {
114 return new LeftProjection();
115 }
116
117 /**
118 * Projects this either as a right.
119 *
120 * @return A right projection of this either.
121 */
122 public final RightProjection right() {
123 return new RightProjection();
124 }
125
126 // right-bias
127
128 /**
129 * Get the value if it is a right or call the supplier and return its value if
130 * not.
131 *
132 * @param supplier called if this is a left
133 * @return the wrapped value or the value from the {@code Supplier}
134 * @since 4.3
135 */
136 public final R getOr(final Supplier<? extends R> supplier) {
137 return right().getOr(supplier);
138 }
139
140 /**
141 * Get the value if it is a right or call the supplier and return its value if
142 * not.
143 *
144 * @param supplier called if this is a left
145 * @return the wrapped value or the value from the {@code Supplier}
146 * @since 2.3
147 * @deprecated since 4.3, use {@link #getOr(Supplier)} instead
148 */
149 @Deprecated public final R getOrElse(final Supplier<? extends R> supplier) {
150 return getOr(supplier);
151 }
152
153 /**
154 * Get the value if it is a right, otherwise returns {@code other}.
155 *
156 * @param <X> default type
157 * @param other value to return if this is a left
158 * @return wrapped value if this is a right, otherwise returns {@code other}
159 * @since 2.3
160 */
161 public final <X extends R> R getOrElse(final X other) {
162 return right().getOrElse(other);
163 }
164
165 /**
166 * Get the value if it is right or null if not.
167 * <p>
168 * Although the use of null is discouraged, code written to use these must
169 * often interface with code that expects and returns nulls.
170 *
171 * @return the contained value or null
172 * @since 2.3
173 */
174 public final R getOrNull() {
175 return right().getOrNull();
176 }
177
178 /**
179 * Get the contained value or throws an error with the supplied message if
180 * left.
181 * <p>
182 * Used when absolutely sure this is a right.
183 *
184 * @param msg the message for the error.
185 * @return the contained value.
186 * @since 2.3
187 */
188 public final R getOrError(final Supplier<String> msg) {
189 return right().getOrError(msg);
190 }
191
192 /**
193 * Get the contained value or throws the supplied throwable if left
194 * <p>
195 * Used when absolutely sure this is a right.
196 *
197 * @param <X> exception type
198 * @param ifUndefined the supplier of the throwable.
199 * @return the contained value.
200 * @throws X the throwable the supplier creates if there is no value.
201 * @since 2.3
202 */
203 public final <X extends Throwable> R getOrThrow(final Supplier<X> ifUndefined) throws X {
204 return right().getOrThrow(ifUndefined);
205 }
206
207 /**
208 * Map the given function across the right hand side value if it is one.
209 *
210 * @param <X> the RHS type
211 * @param f The function to map .
212 * @return A new either value after mapping with the function applied if this
213 * is a Right.
214 * @since 2.2
215 */
216 public final <X> Either<L, X> map(final Function<? super R, X> f) {
217 return right().map(f);
218 }
219
220 /**
221 * Binds the given function across the right hand side value if it is one.
222 *
223 * @param <X> the RHS type
224 * @param <LL> result type
225 * @param f the function to bind.
226 * @return A new either value after binding with the function applied if this
227 * is a Right.
228 * @since 2.2
229 */
230 public final <X, LL extends L> Either<L, X> flatMap(final Function<? super R, Either<LL, X>> f) {
231 return right().flatMap(f);
232 }
233
234 /**
235 * Return `true` if this is a right value <strong>and</strong> applying the
236 * predicate to the contained value returns true.
237 *
238 * @param p the predicate to test.
239 * @return {@code true} if right and the predicate returns true for the right
240 * value, {@code false} otherwise.
241 * @since 2.3
242 */
243 public final boolean exists(final Predicate<? super R> p) {
244 return right().exists(p);
245 }
246
247 /**
248 * Returns <code>true</code> if it is a left or the result of the application
249 * of the given predicate on the contained value.
250 *
251 * @param p The predicate function to test on the contained value.
252 * @return <code>true</code> if no value or returns the result of the
253 * application of the given function to the value.
254 * @since 2.3
255 */
256 public final boolean forall(final Predicate<? super R> p) {
257 return right().forall(p);
258 }
259
260 /**
261 * Perform the given side-effect for the contained element if it is a right
262 *
263 * @param effect the input to use for performing the effect on contained
264 * value.
265 * @since 2.3
266 * @deprecated use {@link #forEach(Consumer)} instead
267 */
268 @Deprecated public final void foreach(final Effect<? super R> effect) {
269 right().foreach(effect);
270 }
271
272 /**
273 * Perform the given side-effect for the contained element if it is a right
274 *
275 * @param effect the input to use for performing the effect on contained
276 * value.
277 * @since 3.1
278 */
279 public final void forEach(final Consumer<? super R> effect) {
280 right().forEach(effect);
281 }
282
283 /**
284 * If this is a right, return the same right. Otherwise, return {@code orElse}
285 * .
286 *
287 * @param orElse either to return if this is left
288 * @return this or {@code orElse}
289 * @since 2.3
290 */
291 public final Either<L, R> orElse(final Either<? extends L, ? extends R> orElse) {
292 return this.orElse(ofInstance(orElse));
293 }
294
295 /**
296 * If this is a right, return the same right. Otherwise, return value supplied
297 * by {@code orElse}.
298 *
299 * @param orElse either to return if this is left
300 * @return this or {@code orElse}
301 * @since 2.3
302 */
303 public final Either<L, R> orElse(final Supplier<? extends Either<? extends L, ? extends R>> orElse) {
304 if (right().isDefined()) {
305 return new Right<>(right().get());
306 }
307
308 @SuppressWarnings("unchecked")
309 final Either<L, R> result = (Either<L, R>) orElse.get();
310 return result;
311 }
312
313 /**
314 * If this is a right return the contained value, else return the result of
315 * running function on left
316 *
317 * @param or Function to run if this is a left
318 * @return contained value of R or result of {@code or}
319 * @since 2.3
320 * @deprecated In favor of {@code rightOr}
321 * @see Either#rightOr(Function)
322 */
323 @Deprecated public final R valueOr(final Function<L, ? extends R> or) {
324 return rightOr(or);
325 }
326
327 /**
328 * If this is a right return the contained value, else return the result of
329 * applying {@code leftTransformer} on left
330 *
331 * @param leftTransformer Function to run on left if this is a left
332 * @return contained value of right or result of {@code leftTransformer}
333 * @since 3.2
334 */
335 public final R rightOr(final Function<L, ? extends R> leftTransformer) {
336 if (right().isDefined()) {
337 return right().get();
338 }
339
340 return leftTransformer.apply(left().get());
341 }
342
343 /**
344 * If this is a left return the contained value, else return the result of
345 * applying {@code rightTransformer} on right
346 *
347 * @param rightTransformer Function to run on right if this is a right
348 * @return contained value of left or result of {@code rightTransformer}
349 * @since 3.2
350 */
351 public final L leftOr(final Function<R, ? extends L> rightTransformer) {
352 if (left().isDefined()) {
353 return left().get();
354 }
355
356 return rightTransformer.apply(right().get());
357 }
358
359 /**
360 * Returns <code>None</code> if this is a left or if the given predicate
361 * <code>p</code> does not hold for the contained value, otherwise, returns a
362 * right in <code>Some</code>.
363 *
364 * @param p The predicate function to test on the right contained value.
365 * @return <code>None</code> if this is a left or if the given predicate
366 * <code>p</code> does not hold for the right contained value, otherwise,
367 * returns a right in <code>Some</code>.
368 * @since 2.3
369 */
370 public final Option<Either<L, R>> filter(final Predicate<? super R> p) {
371 return right().filter(p);
372 }
373
374 /**
375 * Convert this Either to an {@link Optional}. Returns with
376 * {@link Optional#of(Object)} if it is a right, otherwise
377 * {@link Optional#empty()}.
378 *
379 * @return The right projection's value in <code>of</code> if it exists,
380 * otherwise <code>empty</code>.
381 * @since 4.0
382 */
383 public final Optional<R> toOptional() {
384 return right().toOptional();
385 }
386
387 /**
388 * Convert this Either to an Option. Returns <code>Some</code> with a value if
389 * it is a right, otherwise <code>None</code>.
390 *
391 * @return The right projection's value in <code>Some</code> if it exists,
392 * otherwise <code>None</code>.
393 * @since 2.6
394 */
395 public final Option<R> toOption() {
396 return right().toOption();
397 }
398
399 /**
400 * Convert this Either to a {@link Stream}. Returns with
401 * {@link Stream#of(Object)} if it is a right, otherwise
402 * {@link Stream#empty()}.
403 *
404 * @return The right projection's value in <code>of</code> if it exists,
405 * otherwise <code>empty</code>.
406 * @since 4.5.0
407 */
408 public final Stream<R> toStream() {
409 return right().toStream();
410 }
411
412 /**
413 * Will return the supplied Either if this one is right, otherwise this one if
414 * left.
415 *
416 * @param <X> the RHS type
417 * @param e The value to bind with.
418 * @return An either after binding through this projection.
419 * @since 2.6
420 */
421 public <X> Either<L, X> sequence(final Either<L, X> e) {
422 return right().sequence(e);
423 }
424
425 /**
426 * Given a right containing a function from the right type {@code <R>} to a
427 * new type {@code <X>} apply that function to the value inside this either.
428 * When any of the input values are left return that left value.
429 *
430 * @param <X> the RHS type
431 * @param either The either of the function to apply if this is a Right.
432 * @return The result of function application within either.
433 * @since 2.6
434 * @deprecated since 3.0 see {@link #ap}
435 */
436 @Deprecated public <X> Either<L, X> apply(final Either<L, Function<R, X>> either) {
437 return ap(either);
438 }
439
440 /**
441 * Function application on this projection's value.
442 *
443 * @param <X> the RHS type
444 * @param either The either of the function to apply on this projection's
445 * value.
446 * @return The result of function application within either.
447 * @since 3.0
448 */
449 public <X> Either<L, X> ap(final Either<L, Function<R, X>> either) {
450 return either.right().flatMap(this::map);
451 }
452
453 /**
454 * Map the given function across the left hand side value if it is one.
455 *
456 * @param <X> the LHS type
457 * @param f The function to map.
458 * @return A new either value after mapping with the function applied if this
459 * is a Left.
460 * @since 2.2
461 */
462 public final <X> Either<X, R> leftMap(final Function<? super L, X> f) {
463 return left().map(f);
464 }
465
466 //
467 // abstract stuff
468 //
469
470 /**
471 * Returns <code>true</code> if this either is a left, <code>false</code>
472 * otherwise.
473 *
474 * @return <code>true</code> if this either is a left, <code>false</code>
475 * otherwise.
476 */
477 public abstract boolean isLeft();
478
479 /**
480 * Returns <code>true</code> if this either is a right, <code>false</code>
481 * otherwise.
482 *
483 * @return <code>true</code> if this either is a right, <code>false</code>
484 * otherwise.
485 */
486 public abstract boolean isRight();
487
488 /**
489 * If this is a left, then return the left value in right, or vice versa.
490 *
491 * @return an Either that is a Left if this is a Right or a Right if this is a
492 * Left. The value remains the same.
493 */
494 public abstract Either<R, L> swap();
495
496 /**
497 * Applies the function to the wrapped value, applying ifLeft if this is a
498 * Left and ifRight if this is a Right.
499 *
500 * @param <V> the destination type
501 * @param ifLeft the function to apply if this is a Left
502 * @param ifRight the function to apply if this is a Right
503 * @return the result of the applies function
504 */
505 public abstract <V> V fold(Function<? super L, V> ifLeft, Function<? super R, V> ifRight);
506
507 /**
508 * Map the given functions across the appropriate side.
509 *
510 * @param <LL> the LHS type
511 * @param <RR> the RHS type
512 * @param ifLeft The function to map if this Either is a left.
513 * @param ifRight The function to map if this Either is a right.
514 * @return A new either value after mapping with the appropriate function
515 * applied.
516 * @since 2.2
517 */
518 public abstract <LL, RR> Either<LL, RR> bimap(final Function<? super L, ? extends LL> ifLeft, final Function<? super R, ? extends RR> ifRight);
519
520 //
521 // internal only, should not be accessed from outside this class
522 //
523
524 // value accessor for Left
525 L getLeft() {
526 throw new NoSuchElementException();
527 }
528
529 // value accessor for Right
530 R getRight() {
531 throw new NoSuchElementException();
532 }
533
534 //
535 // inner class implementations
536 //
537
538 static final class Left<L, R> extends Either<L, R> {
539 private static final long serialVersionUID = -6846704510630179771L;
540
541 private final L value;
542
543 public Left(final L value) {
544 requireNonNull(value);
545 this.value = value;
546 }
547
548 @Override final L getLeft() {
549 return value;
550 }
551
552 @Override public boolean isLeft() {
553 return true;
554 }
555
556 @Override public boolean isRight() {
557 return false;
558 }
559
560 @Override public Either<R, L> swap() {
561 return right(value);
562 }
563
564 @Override public <V> V fold(final Function<? super L, V> ifLeft, final Function<? super R, V> ifRight) {
565 return ifLeft.apply(value);
566 }
567
568 @Override public <LL, RR> Either<LL, RR> bimap(final Function<? super L, ? extends LL> ifLeft, final Function<? super R, ? extends RR> ifRight) {
569 @SuppressWarnings("unchecked")
570 final Either<LL, RR> map = (Either<LL, RR>) left().map(ifLeft);
571 return map;
572 }
573
574 @Override public boolean equals(final Object o) {
575 if (this == o) {
576 return true;
577 }
578 if ((o == null) || !(o instanceof Left<?, ?>)) {
579 return false;
580 }
581 return value.equals(((Left<?, ?>) o).value);
582 }
583
584 @Override public int hashCode() {
585 return ~value.hashCode();
586 }
587
588 @Override public String toString() {
589 return "Either.Left(" + value.toString() + ")";
590 }
591 }
592
593 static final class Right<L, R> extends Either<L, R> {
594 private static final long serialVersionUID = 5025077305715784930L;
595
596 private final R value;
597
598 public Right(final R value) {
599 requireNonNull(value);
600 this.value = value;
601 }
602
603 @Override final R getRight() {
604 return value;
605 }
606
607 @Override public boolean isRight() {
608 return true;
609 }
610
611 @Override public boolean isLeft() {
612 return false;
613 }
614
615 @Override public Either<R, L> swap() {
616 return left(value);
617 }
618
619 @Override public <V> V fold(final Function<? super L, V> ifLeft, final Function<? super R, V> ifRight) {
620 return ifRight.apply(value);
621 }
622
623 @Override public <LL, RR> Either<LL, RR> bimap(final Function<? super L, ? extends LL> ifLeft, final Function<? super R, ? extends RR> ifRight) {
624 @SuppressWarnings("unchecked")
625 final Either<LL, RR> map = (Either<LL, RR>) right().map(ifRight);
626 return map;
627 }
628
629 @Override public boolean equals(final Object o) {
630 if (this == o) {
631 return true;
632 }
633 if ((o == null) || !(o instanceof Right<?, ?>)) {
634 return false;
635 }
636 return value.equals(((Right<?, ?>) o).value);
637 }
638
639 @Override public int hashCode() {
640 return value.hashCode();
641 }
642
643 @Override public String toString() {
644 return "Either.Right(" + value.toString() + ")";
645 }
646 }
647
648 /**
649 * Holds the common implementation for both projections.
650 */
651 abstract class AbstractProjection<A, B> implements Projection<A, B, L, R> {
652 @Override public final Iterator<A> iterator() {
653 return toOption().iterator();
654 }
655
656 @Override public final Either<L, R> either() {
657 return Either.this;
658 }
659
660 @Override public final boolean isEmpty() {
661 return !isDefined();
662 }
663
664 @Override public final Option<A> toOption() {
665 return isDefined() ? some(get()) : none();
666 }
667
668 @Override public final Optional<A> toOptional() {
669 return toOption().toOptional();
670 }
671
672 @Override public final Stream<A> toStream() {
673 return toOption().toStream();
674 }
675
676 @Override public final boolean exists(final Predicate<? super A> f) {
677 return isDefined() && f.test(get());
678 }
679
680 @Override final public A getOrNull() {
681 return isDefined() ? get() : null;
682 }
683
684 @Override public final boolean forall(final Predicate<? super A> f) {
685 return isEmpty() || f.test(get());
686 }
687
688 @Override public final A getOrError(final Supplier<String> err) {
689 return toOption().getOrError(err);
690 }
691
692 @Override public <X extends Throwable> A getOrThrow(final Supplier<X> ifUndefined) throws X {
693 return toOption().getOrThrow(ifUndefined);
694 }
695
696 @Override public final A getOr(final Supplier<? extends A> a) {
697 return isDefined() ? get() : a.get();
698 }
699
700 @Deprecated @Override public final A getOrElse(final Supplier<? extends A> a) {
701 return isDefined() ? get() : a.get();
702 }
703
704 @Override public final <X extends A> A getOrElse(final X x) {
705 return isDefined() ? get() : x;
706 }
707
708 @Deprecated @Override public final void foreach(final Effect<? super A> f) {
709 this.forEach(f::apply);
710 }
711
712 @Override public final void forEach(final Consumer<? super A> f) {
713 if (isDefined()) {
714 f.accept(get());
715 }
716 }
717 }
718
719 /**
720 * A left projection of an either value.
721 */
722 public final class LeftProjection extends AbstractProjection<L, R> implements Projection<L, R, L, R> {
723 private LeftProjection() {}
724
725 public L get() {
726 return getLeft();
727 }
728
729 @Override public boolean isDefined() {
730 return isLeft();
731 }
732
733 public L on(final Function<? super R, ? extends L> f) {
734 return isLeft() ? get() : f.apply(right().get());
735 }
736
737 //
738 // definitions that can't be shared without higher-kinded types
739 //
740
741 /**
742 * Map the given function across this projection's value if it has one.
743 *
744 * @param <X> the LHS type
745 * @param f The function to map across this projection, must not return null
746 * @return A new either value after mapping.
747 */
748 public <X> Either<X, R> map(final Function<? super L, X> f) {
749 return isLeft() ? new Left<>(f.apply(get())) : this.<X> toRight();
750 }
751
752 /**
753 * Binds the given function across this projection's value if it has one.
754 *
755 * @param <X> the LHS type
756 * @param <RR> The existing RHS or a subtype
757 * @param f The function to bind across this projection.
758 * @return A new either value after binding.
759 */
760 public <X, RR extends R> Either<X, R> flatMap(final Function<? super L, Either<X, RR>> f) {
761 if (isLeft()) {
762 @SuppressWarnings("unchecked")
763 final Either<X, R> result = (Either<X, R>) f.apply(get());
764 return result;
765 } else {
766 return this.toRight();
767 }
768 }
769
770 <X> Right<X, R> toRight() {
771 return new Right<>(getRight());
772 }
773
774 /**
775 * Anonymous bind through this projection.
776 *
777 * @param <X> the LHS type
778 * @param e The value to bind with.
779 * @return An either after binding through this projection.
780 */
781 public <X> Either<X, R> sequence(final Either<X, R> e) {
782 return flatMap(Functions.<L, Either<X, R>> constant(e));
783 }
784
785 /**
786 * Returns <code>None</code> if this projection has no value or if the given
787 * predicate <code>p</code> does not hold for the value, otherwise, returns
788 * a left in <code>Some</code>.
789 *
790 * @param <X> the RHS type
791 * @param f The predicate function to test on this projection's value.
792 * @return <code>None</code> if this projection has no value or if the given
793 * predicate <code>p</code> does not hold for the value, otherwise, returns
794 * a left in <code>Some</code>.
795 */
796 public <X> Option<Either<L, X>> filter(final Predicate<? super L> f) {
797 if (isLeft() && f.test(get())) {
798 final Either<L, X> result = new Left<>(get());
799 return some(result);
800 }
801 return none();
802 }
803
804 /**
805 * Function application on this projection's value.
806 *
807 * @param <X> the LHS type
808 * @param either The either of the function to apply on this projection's
809 * value.
810 * @return The result of function application within either.
811 * @since 3.0
812 */
813 public <X> Either<X, R> ap(final Either<Function<L, X>, R> either) {
814 return either.left().flatMap(this::map);
815 }
816
817 /**
818 * Function application on this projection's value.
819 *
820 * @param <X> the LHS type
821 * @param either The either of the function to apply on this projection's
822 * value.
823 * @return The result of function application within either.
824 * @see #ap ap
825 * @deprecated since 3.0
826 */
827 @Deprecated public <X> Either<X, R> apply(final Either<Function<L, X>, R> either) {
828 return ap(either);
829 }
830
831 /**
832 * Coerces our right type as X. Dangerous, isLeft() must be true
833 *
834 * @param <X> the type to coerce to.
835 * @return an either with the coerced right type.
836 */
837 <X> Either<L, X> as() {
838 return left(get());
839 }
840 }
841
842 /**
843 * A right projection of an either value.
844 */
845 public final class RightProjection extends AbstractProjection<R, L> implements Projection<R, L, L, R> {
846 private RightProjection() {}
847
848 @Override public R get() {
849 return getRight();
850 }
851
852 @Override public boolean isDefined() {
853 return isRight();
854 }
855
856 @Override public R on(final Function<? super L, ? extends R> f) {
857 return isRight() ? get() : f.apply(left().get());
858 }
859
860 //
861 // definitions that can't be shared without higher-kinded types
862 //
863
864 /**
865 * Map the given function across this projection's value if it has one.
866 *
867 * @param <X> the RHS type
868 * @param f The function to map across this projection.
869 * @return A new either value after mapping.
870 */
871 public <X> Either<L, X> map(final Function<? super R, X> f) {
872 return isRight() ? new Right<>(f.apply(get())) : this.<X> toLeft();
873 }
874
875 /**
876 * Binds the given function across this projection's value if it has one.
877 *
878 * @param <X> the RHS type
879 * @param <LL> The existing LHS or a subtype
880 * @param f The function to bind across this projection.
881 * @return A new either value after binding.
882 */
883 public <X, LL extends L> Either<L, X> flatMap(final Function<? super R, Either<LL, X>> f) {
884 if (isRight()) {
885 @SuppressWarnings("unchecked")
886 final Either<L, X> result = (Either<L, X>) f.apply(get());
887 return result;
888 } else {
889 return this.toLeft();
890 }
891 }
892
893 <X> Left<L, X> toLeft() {
894 return new Left<>(left().get());
895 }
896
897 /**
898 * Anonymous bind through this projection.
899 *
900 * @param <X> the RHS type
901 * @param e The value to bind with.
902 * @return An either after binding through this projection.
903 */
904 public <X> Either<L, X> sequence(final Either<L, X> e) {
905 return flatMap(Functions.constant(e));
906 }
907
908 /**
909 * Returns <code>None</code> if this projection has no value or if the given
910 * predicate <code>p</code> does not hold for the value, otherwise, returns
911 * a right in <code>Some</code>.
912 *
913 * @param <X> the LHS type
914 * @param f The predicate function to test on this projection's value.
915 * @return <code>None</code> if this projection has no value or if the given
916 * predicate <code>p</code> does not hold for the value, otherwise, returns
917 * a right in <code>Some</code>.
918 */
919 public <X> Option<Either<X, R>> filter(final Predicate<? super R> f) {
920 if (isRight() && f.test(get())) {
921 final Either<X, R> result = new Right<>(get());
922 return some(result);
923 }
924 return none();
925 }
926
927 /**
928 * Function application on this projection's value.
929 *
930 * @param <X> the RHS type
931 * @param either The either of the function to apply on this projection's
932 * value.
933 * @return The result of function application within either.
934 * @since 3.0
935 */
936 public <X> Either<L, X> ap(final Either<L, Function<R, X>> either) {
937 return either.right().flatMap(this::map);
938 }
939
940 /**
941 * Function application on this projection's value.
942 *
943 * @param <X> the RHS type
944 * @param either The either of the function to apply on this projection's
945 * value.
946 * @return The result of function application within either.
947 * @deprecated since 3.0 see ap
948 */
949 @Deprecated public <X> Either<L, X> apply(final Either<L, Function<R, X>> either) {
950 return ap(either);
951 }
952
953 /**
954 * Coerces our left type as X. Dangerous, isRight() must be true
955 *
956 * @param <X> the type to coerce to.
957 * @return an either with the coerced left type.
958 */
959 <X> Either<X, R> as() {
960 return right(get());
961 }
962 }
963
964 public interface Projection<A, B, L, R> extends Maybe<A> {
965 /**
966 * The either value underlying this projection.
967 *
968 * @return The either value underlying this projection.
969 */
970 Either<L, R> either();
971
972 /**
973 * Returns this projection's value in <code>Some</code> if it exists,
974 * otherwise <code>None</code>.
975 *
976 * @return This projection's value in <code>Some</code> if it exists,
977 * otherwise <code>None</code>.
978 */
979 Option<? super A> toOption();
980
981 /**
982 * Returns this projection's value in {@link Optional#of} if it exists,
983 * otherwise {@link Optional#empty()}.
984 *
985 * @return This projection's value in <code>of</code> if it exists,
986 * otherwise <code>empty</code>.
987 * @since 4.0
988 */
989 Optional<? super A> toOptional();
990
991 /**
992 * Returns this projection's value in {@link Stream#of} if it exists,
993 * otherwise {@link Stream#empty()}.
994 *
995 * @return This projection's value in <code>of</code> if it exists,
996 * otherwise <code>empty</code>.
997 * @since 4.5.0
998 */
999 Stream<? super A> toStream();
1000
1001 /**
1002 * The value of this projection or the result of the given function on the
1003 * opposing projection's value.
1004 *
1005 * @param f The function to execute if this projection has no value.
1006 * @return The value of this projection or the result of the given function
1007 * on the opposing projection's value.
1008 */
1009 A on(Function<? super B, ? extends A> f);
1010 }
1011 }