View Javadoc

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 }