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 java.io.Serializable;
19 import java.util.Iterator;
20 import java.util.NoSuchElementException;
21 import java.util.Optional;
22 import java.util.function.Consumer;
23 import java.util.function.Function;
24 import java.util.function.Predicate;
25 import java.util.function.Supplier;
26 import java.util.stream.Stream;
27
28 import static io.atlassian.fugue.Option.none;
29 import static io.atlassian.fugue.Option.some;
30 import static io.atlassian.fugue.Suppliers.ofInstance;
31 import static java.util.Objects.requireNonNull;
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 * Return a <code>Right</code> if this is a <code>Right</code> and the
376 * contained values satisfies the given predicate.
377 *
378 * If this is a <code>Right</code> but the predicate is not satisfied, return
379 * a <code>Left</code> with the value provided by the orElseSupplier.
380 *
381 * Return a <code>Left</code> if this a <code>Left</code> with the contained
382 * value.
383 *
384 * @param p The predicate function to test on the right contained value.
385 * @param orElseSupplier The supplier to execute when is a right, and
386 * predicate is unsatisfied
387 * @return a new Either that will be either the existing left/right or a left
388 * with result of orElseSupplier
389 * @since 4.7.0
390 */
391 public final Either<L, R> filterOrElse(Predicate<? super R> p, Supplier<? extends L> orElseSupplier) {
392 return right().filterOrElse(p, orElseSupplier);
393 }
394
395 /**
396 * Convert this Either to an {@link Optional}. Returns with
397 * {@link Optional#of(Object)} if it is a right, otherwise
398 * {@link Optional#empty()}.
399 *
400 * @return The right projection's value in <code>of</code> if it exists,
401 * otherwise <code>empty</code>.
402 * @since 4.0
403 */
404 public final Optional<R> toOptional() {
405 return right().toOptional();
406 }
407
408 /**
409 * Convert this Either to an Option. Returns <code>Some</code> with a value if
410 * it is a right, otherwise <code>None</code>.
411 *
412 * @return The right projection's value in <code>Some</code> if it exists,
413 * otherwise <code>None</code>.
414 * @since 2.6
415 */
416 public final Option<R> toOption() {
417 return right().toOption();
418 }
419
420 /**
421 * Convert this Either to a {@link Stream}. Returns with
422 * {@link Stream#of(Object)} if it is a right, otherwise
423 * {@link Stream#empty()}.
424 *
425 * @return The right projection's value in <code>of</code> if it exists,
426 * otherwise <code>empty</code>.
427 * @since 4.5.0
428 */
429 public final Stream<R> toStream() {
430 return right().toStream();
431 }
432
433 /**
434 * Will return the supplied Either if this one is right, otherwise this one if
435 * left.
436 *
437 * @param <X> the RHS type
438 * @param e The value to bind with.
439 * @return An either after binding through this projection.
440 * @since 2.6
441 */
442 public <X> Either<L, X> sequence(final Either<L, X> e) {
443 return right().sequence(e);
444 }
445
446 /**
447 * Given a right containing a function from the right type {@code <R>} to a
448 * new type {@code <X>} apply that function to the value inside this either.
449 * When any of the input values are left return that left value.
450 *
451 * @param <X> the RHS type
452 * @param either The either of the function to apply if this is a Right.
453 * @return The result of function application within either.
454 * @since 2.6
455 * @deprecated since 3.0 see {@link #ap}
456 */
457 @Deprecated public <X> Either<L, X> apply(final Either<L, Function<R, X>> either) {
458 return ap(either);
459 }
460
461 /**
462 * Function application on this projection's value.
463 *
464 * @param <X> the RHS type
465 * @param either The either of the function to apply on this projection's
466 * value.
467 * @return The result of function application within either.
468 * @since 3.0
469 */
470 public <X> Either<L, X> ap(final Either<L, Function<R, X>> either) {
471 return either.right().flatMap(this::map);
472 }
473
474 /**
475 * Map the given function across the left hand side value if it is one.
476 *
477 * @param <X> the LHS type
478 * @param f The function to map.
479 * @return A new either value after mapping with the function applied if this
480 * is a Left.
481 * @since 2.2
482 */
483 public final <X> Either<X, R> leftMap(final Function<? super L, X> f) {
484 return left().map(f);
485 }
486
487 //
488 // abstract stuff
489 //
490
491 /**
492 * Returns <code>true</code> if this either is a left, <code>false</code>
493 * otherwise.
494 *
495 * @return <code>true</code> if this either is a left, <code>false</code>
496 * otherwise.
497 */
498 public abstract boolean isLeft();
499
500 /**
501 * Returns <code>true</code> if this either is a right, <code>false</code>
502 * otherwise.
503 *
504 * @return <code>true</code> if this either is a right, <code>false</code>
505 * otherwise.
506 */
507 public abstract boolean isRight();
508
509 /**
510 * If this is a left, then return the left value in right, or vice versa.
511 *
512 * @return an Either that is a Left if this is a Right or a Right if this is a
513 * Left. The value remains the same.
514 */
515 public abstract Either<R, L> swap();
516
517 /**
518 * Applies the function to the wrapped value, applying ifLeft if this is a
519 * Left and ifRight if this is a Right.
520 *
521 * @param <V> the destination type
522 * @param ifLeft the function to apply if this is a Left
523 * @param ifRight the function to apply if this is a Right
524 * @return the result of the applies function
525 */
526 public abstract <V> V fold(Function<? super L, V> ifLeft, Function<? super R, V> ifRight);
527
528 /**
529 * Map the given functions across the appropriate side.
530 *
531 * @param <LL> the LHS type
532 * @param <RR> the RHS type
533 * @param ifLeft The function to map if this Either is a left.
534 * @param ifRight The function to map if this Either is a right.
535 * @return A new either value after mapping with the appropriate function
536 * applied.
537 * @since 2.2
538 */
539 public abstract <LL, RR> Either<LL, RR> bimap(final Function<? super L, ? extends LL> ifLeft, final Function<? super R, ? extends RR> ifRight);
540
541 //
542 // internal only, should not be accessed from outside this class
543 //
544
545 // value accessor for Left
546 L getLeft() {
547 throw new NoSuchElementException();
548 }
549
550 // value accessor for Right
551 R getRight() {
552 throw new NoSuchElementException();
553 }
554
555 //
556 // inner class implementations
557 //
558
559 static final class Left<L, R> extends Either<L, R> {
560 private static final long serialVersionUID = -6846704510630179771L;
561
562 private final L value;
563
564 public Left(final L value) {
565 requireNonNull(value);
566 this.value = value;
567 }
568
569 @Override final L getLeft() {
570 return value;
571 }
572
573 @Override public boolean isLeft() {
574 return true;
575 }
576
577 @Override public boolean isRight() {
578 return false;
579 }
580
581 @Override public Either<R, L> swap() {
582 return right(value);
583 }
584
585 @Override public <V> V fold(final Function<? super L, V> ifLeft, final Function<? super R, V> ifRight) {
586 return ifLeft.apply(value);
587 }
588
589 @Override public <LL, RR> Either<LL, RR> bimap(final Function<? super L, ? extends LL> ifLeft, final Function<? super R, ? extends RR> ifRight) {
590 @SuppressWarnings("unchecked")
591 final Either<LL, RR> map = (Either<LL, RR>) left().map(ifLeft);
592 return map;
593 }
594
595 @Override public boolean equals(final Object o) {
596 if (this == o) {
597 return true;
598 }
599 if ((o == null) || !(o instanceof Left<?, ?>)) {
600 return false;
601 }
602 return value.equals(((Left<?, ?>) o).value);
603 }
604
605 @Override public int hashCode() {
606 return ~value.hashCode();
607 }
608
609 @Override public String toString() {
610 return "Either.Left(" + value.toString() + ")";
611 }
612 }
613
614 static final class Right<L, R> extends Either<L, R> {
615 private static final long serialVersionUID = 5025077305715784930L;
616
617 private final R value;
618
619 public Right(final R value) {
620 requireNonNull(value);
621 this.value = value;
622 }
623
624 @Override final R getRight() {
625 return value;
626 }
627
628 @Override public boolean isRight() {
629 return true;
630 }
631
632 @Override public boolean isLeft() {
633 return false;
634 }
635
636 @Override public Either<R, L> swap() {
637 return left(value);
638 }
639
640 @Override public <V> V fold(final Function<? super L, V> ifLeft, final Function<? super R, V> ifRight) {
641 return ifRight.apply(value);
642 }
643
644 @Override public <LL, RR> Either<LL, RR> bimap(final Function<? super L, ? extends LL> ifLeft, final Function<? super R, ? extends RR> ifRight) {
645 @SuppressWarnings("unchecked")
646 final Either<LL, RR> map = (Either<LL, RR>) right().map(ifRight);
647 return map;
648 }
649
650 @Override public boolean equals(final Object o) {
651 if (this == o) {
652 return true;
653 }
654 if ((o == null) || !(o instanceof Right<?, ?>)) {
655 return false;
656 }
657 return value.equals(((Right<?, ?>) o).value);
658 }
659
660 @Override public int hashCode() {
661 return value.hashCode();
662 }
663
664 @Override public String toString() {
665 return "Either.Right(" + value.toString() + ")";
666 }
667 }
668
669 /**
670 * Holds the common implementation for both projections.
671 */
672 abstract class AbstractProjection<A, B> implements Projection<A, B, L, R> {
673 @Override public final Iterator<A> iterator() {
674 return toOption().iterator();
675 }
676
677 @Override public final Either<L, R> either() {
678 return Either.this;
679 }
680
681 @Override public final boolean isEmpty() {
682 return !isDefined();
683 }
684
685 @Override public final Option<A> toOption() {
686 return isDefined() ? some(get()) : none();
687 }
688
689 @Override public final Optional<A> toOptional() {
690 return toOption().toOptional();
691 }
692
693 @Override public final Stream<A> toStream() {
694 return toOption().toStream();
695 }
696
697 @Override public final boolean exists(final Predicate<? super A> f) {
698 return isDefined() && f.test(get());
699 }
700
701 @Override final public A getOrNull() {
702 return isDefined() ? get() : null;
703 }
704
705 @Override public final boolean forall(final Predicate<? super A> f) {
706 return isEmpty() || f.test(get());
707 }
708
709 @Override public final A getOrError(final Supplier<String> err) {
710 return toOption().getOrError(err);
711 }
712
713 @Override public <X extends Throwable> A getOrThrow(final Supplier<X> ifUndefined) throws X {
714 return toOption().getOrThrow(ifUndefined);
715 }
716
717 @Override public final A getOr(final Supplier<? extends A> a) {
718 return isDefined() ? get() : a.get();
719 }
720
721 @Deprecated @Override public final A getOrElse(final Supplier<? extends A> a) {
722 return isDefined() ? get() : a.get();
723 }
724
725 @Override public final <X extends A> A getOrElse(final X x) {
726 return isDefined() ? get() : x;
727 }
728
729 @Deprecated @Override public final void foreach(final Effect<? super A> f) {
730 this.forEach(f::apply);
731 }
732
733 @Override public final void forEach(final Consumer<? super A> f) {
734 if (isDefined()) {
735 f.accept(get());
736 }
737 }
738 }
739
740 /**
741 * A left projection of an either value.
742 */
743 public final class LeftProjection extends AbstractProjection<L, R> implements Projection<L, R, L, R> {
744 private LeftProjection() {}
745
746 public L get() {
747 return getLeft();
748 }
749
750 @Override public boolean isDefined() {
751 return isLeft();
752 }
753
754 public L on(final Function<? super R, ? extends L> f) {
755 return isLeft() ? get() : f.apply(right().get());
756 }
757
758 //
759 // definitions that can't be shared without higher-kinded types
760 //
761
762 /**
763 * Map the given function across this projection's value if it has one.
764 *
765 * @param <X> the LHS type
766 * @param f The function to map across this projection, must not return null
767 * @return A new either value after mapping.
768 */
769 public <X> Either<X, R> map(final Function<? super L, X> f) {
770 return isLeft() ? new Left<>(f.apply(get())) : this.<X> toRight();
771 }
772
773 /**
774 * Binds the given function across this projection's value if it has one.
775 *
776 * @param <X> the LHS type
777 * @param <RR> The existing RHS or a subtype
778 * @param f The function to bind across this projection.
779 * @return A new either value after binding.
780 */
781 public <X, RR extends R> Either<X, R> flatMap(final Function<? super L, Either<X, RR>> f) {
782 if (isLeft()) {
783 @SuppressWarnings("unchecked")
784 final Either<X, R> result = (Either<X, R>) f.apply(get());
785 return result;
786 } else {
787 return this.toRight();
788 }
789 }
790
791 <X> Right<X, R> toRight() {
792 return new Right<>(getRight());
793 }
794
795 /**
796 * Anonymous bind through this projection.
797 *
798 * @param <X> the LHS type
799 * @param e The value to bind with.
800 * @return An either after binding through this projection.
801 */
802 public <X> Either<X, R> sequence(final Either<X, R> e) {
803 return flatMap(Functions.<L, Either<X, R>> constant(e));
804 }
805
806 /**
807 * Returns <code>None</code> if this projection has no value or if the given
808 * predicate <code>p</code> does not hold for the value, otherwise, returns
809 * a left in <code>Some</code>.
810 *
811 * @param <X> the RHS type
812 * @param f The predicate function to test on this projection's value.
813 * @return <code>None</code> if this projection has no value or if the given
814 * predicate <code>p</code> does not hold for the value, otherwise, returns
815 * a left in <code>Some</code>.
816 */
817 public <X> Option<Either<L, X>> filter(final Predicate<? super L> f) {
818 if (isLeft() && f.test(get())) {
819 final Either<L, X> result = new Left<>(get());
820 return some(result);
821 }
822 return none();
823 }
824
825 /**
826 * Return a <code>Left</code> if this is a <code>Left</code> and the
827 * contained values satisfies the given predicate.
828 *
829 * If this is a <code>Left</code> but the predicate is not satisfied, return
830 * a <code>Right</code> with the value provided by the orElseSupplier.
831 *
832 * Return a <code>Right</code> if this a <code>Right</code> with the
833 * contained value.
834 *
835 * @param p The predicate function to test on the right contained value.
836 * @param orElseSupplier The supplier to execute when is a left, and
837 * predicate is unsatisfied
838 * @return a new Either that will be either the existing left/right or a
839 * right with result of orElseSupplier
840 * @since 4.7.0
841 */
842 @SuppressWarnings("unchecked") public Either<L, R> filterOrElse(Predicate<? super L> p, Supplier<? extends R> orElseSupplier) {
843 if (isLeft()) {
844 L value = get();
845 if (p.test(value)) {
846 return new Left<>(value);
847 } else {
848 return (Either<L, R>) right(orElseSupplier.get());
849 }
850 } else {
851 return this.toRight();
852 }
853 }
854
855 /**
856 * Function application on this projection's value.
857 *
858 * @param <X> the LHS type
859 * @param either The either of the function to apply on this projection's
860 * value.
861 * @return The result of function application within either.
862 * @since 3.0
863 */
864 public <X> Either<X, R> ap(final Either<Function<L, X>, R> either) {
865 return either.left().flatMap(this::map);
866 }
867
868 /**
869 * Function application on this projection's value.
870 *
871 * @param <X> the LHS type
872 * @param either The either of the function to apply on this projection's
873 * value.
874 * @return The result of function application within either.
875 * @see #ap ap
876 * @deprecated since 3.0
877 */
878 @Deprecated public <X> Either<X, R> apply(final Either<Function<L, X>, R> either) {
879 return ap(either);
880 }
881
882 /**
883 * Coerces our right type as X. Dangerous, isLeft() must be true
884 *
885 * @param <X> the type to coerce to.
886 * @return an either with the coerced right type.
887 */
888 <X> Either<L, X> as() {
889 return left(get());
890 }
891 }
892
893 /**
894 * A right projection of an either value.
895 */
896 public final class RightProjection extends AbstractProjection<R, L> implements Projection<R, L, L, R> {
897 private RightProjection() {}
898
899 @Override public R get() {
900 return getRight();
901 }
902
903 @Override public boolean isDefined() {
904 return isRight();
905 }
906
907 @Override public R on(final Function<? super L, ? extends R> f) {
908 return isRight() ? get() : f.apply(left().get());
909 }
910
911 //
912 // definitions that can't be shared without higher-kinded types
913 //
914
915 /**
916 * Map the given function across this projection's value if it has one.
917 *
918 * @param <X> the RHS type
919 * @param f The function to map across this projection.
920 * @return A new either value after mapping.
921 */
922 public <X> Either<L, X> map(final Function<? super R, X> f) {
923 return isRight() ? new Right<>(f.apply(get())) : this.<X> toLeft();
924 }
925
926 /**
927 * Binds the given function across this projection's value if it has one.
928 *
929 * @param <X> the RHS type
930 * @param <LL> The existing LHS or a subtype
931 * @param f The function to bind across this projection.
932 * @return A new either value after binding.
933 */
934 public <X, LL extends L> Either<L, X> flatMap(final Function<? super R, Either<LL, X>> f) {
935 if (isRight()) {
936 @SuppressWarnings("unchecked")
937 final Either<L, X> result = (Either<L, X>) f.apply(get());
938 return result;
939 } else {
940 return this.toLeft();
941 }
942 }
943
944 <X> Left<L, X> toLeft() {
945 return new Left<>(left().get());
946 }
947
948 /**
949 * Anonymous bind through this projection.
950 *
951 * @param <X> the RHS type
952 * @param e The value to bind with.
953 * @return An either after binding through this projection.
954 */
955 public <X> Either<L, X> sequence(final Either<L, X> e) {
956 return flatMap(Functions.constant(e));
957 }
958
959 /**
960 * Returns <code>None</code> if this projection has no value or if the given
961 * predicate <code>p</code> does not hold for the value, otherwise, returns
962 * a right in <code>Some</code>.
963 *
964 * @param <X> the LHS type
965 * @param f The predicate function to test on this projection's value.
966 * @return <code>None</code> if this projection has no value or if the given
967 * predicate <code>p</code> does not hold for the value, otherwise, returns
968 * a right in <code>Some</code>.
969 */
970 public <X> Option<Either<X, R>> filter(final Predicate<? super R> f) {
971 if (isRight() && f.test(get())) {
972 final Either<X, R> result = new Right<>(get());
973 return some(result);
974 }
975 return none();
976 }
977
978 /**
979 * Return a <code>Right</code> if this is a <code>Right</code> and the
980 * contained values satisfies the given predicate.
981 *
982 * If this is a <code>Right</code> but the predicate is not satisfied,
983 * return a <code>Left</code> with the value provided by the orElseSupplier.
984 *
985 * Return a <code>Left</code> if this a <code>Left</code> with the contained
986 * value.
987 *
988 * @param p The predicate function to test on the right contained value.
989 * @param orElseSupplier The supplier to execute when is a right, and
990 * predicate is unsatisfied
991 * @return a new Either that will be either the existing left/right or a
992 * left with result of orElseSupplier
993 * @since 4.7.0
994 */
995 @SuppressWarnings("unchecked") public Either<L, R> filterOrElse(Predicate<? super R> p, Supplier<? extends L> orElseSupplier) {
996 if (isRight()) {
997 R value = get();
998 if (p.test(value)) {
999 return new Right<>(value);
1000 } else {
1001 return (Either<L, R>) left(orElseSupplier.get());
1002 }
1003 } else {
1004 return this.toLeft();
1005 }
1006 }
1007
1008 /**
1009 * Function application on this projection's value.
1010 *
1011 * @param <X> the RHS type
1012 * @param either The either of the function to apply on this projection's
1013 * value.
1014 * @return The result of function application within either.
1015 * @since 3.0
1016 */
1017 public <X> Either<L, X> ap(final Either<L, Function<R, X>> either) {
1018 return either.right().flatMap(this::map);
1019 }
1020
1021 /**
1022 * Function application on this projection's value.
1023 *
1024 * @param <X> the RHS type
1025 * @param either The either of the function to apply on this projection's
1026 * value.
1027 * @return The result of function application within either.
1028 * @deprecated since 3.0 see ap
1029 */
1030 @Deprecated public <X> Either<L, X> apply(final Either<L, Function<R, X>> either) {
1031 return ap(either);
1032 }
1033
1034 /**
1035 * Coerces our left type as X. Dangerous, isRight() must be true
1036 *
1037 * @param <X> the type to coerce to.
1038 * @return an either with the coerced left type.
1039 */
1040 <X> Either<X, R> as() {
1041 return right(get());
1042 }
1043 }
1044
1045 public interface Projection<A, B, L, R> extends Maybe<A> {
1046 /**
1047 * The either value underlying this projection.
1048 *
1049 * @return The either value underlying this projection.
1050 */
1051 Either<L, R> either();
1052
1053 /**
1054 * Returns this projection's value in <code>Some</code> if it exists,
1055 * otherwise <code>None</code>.
1056 *
1057 * @return This projection's value in <code>Some</code> if it exists,
1058 * otherwise <code>None</code>.
1059 */
1060 Option<? super A> toOption();
1061
1062 /**
1063 * Returns this projection's value in {@link Optional#of} if it exists,
1064 * otherwise {@link Optional#empty()}.
1065 *
1066 * @return This projection's value in <code>of</code> if it exists,
1067 * otherwise <code>empty</code>.
1068 * @since 4.0
1069 */
1070 Optional<? super A> toOptional();
1071
1072 /**
1073 * Returns this projection's value in {@link Stream#of} if it exists,
1074 * otherwise {@link Stream#empty()}.
1075 *
1076 * @return This projection's value in <code>of</code> if it exists,
1077 * otherwise <code>empty</code>.
1078 * @since 4.5.0
1079 */
1080 Stream<? super A> toStream();
1081
1082 /**
1083 * The value of this projection or the result of the given function on the
1084 * opposing projection's value.
1085 *
1086 * @param f The function to execute if this projection has no value.
1087 * @return The value of this projection or the result of the given function
1088 * on the opposing projection's value.
1089 */
1090 A on(Function<? super B, ? extends A> f);
1091 }
1092 }