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 java.io.Serializable;
19  import java.util.Iterator;
20  import java.util.NoSuchElementException;
21  import java.util.Objects;
22  import java.util.Optional;
23  import java.util.function.Consumer;
24  import java.util.function.Function;
25  import java.util.function.Predicate;
26  import java.util.function.Supplier;
27  import java.util.stream.Stream;
28  
29  import static io.atlassian.fugue.Suppliers.ofInstance;
30  import static java.util.Objects.requireNonNull;
31  
32  /**
33   * A class that encapsulates missing values. An Option may be either
34   * <em>some</em> value or <em>none</em>.
35   * <p>
36   * If it is a value it may be tested with the {@link #isDefined()} method, but
37   * more often it is useful to either return the value or an alternative if
38   * {@link #getOrElse(Object) not set}, or {@link #map(Function) map} or
39   * {@link #filter(Predicate) filter}.
40   * <p>
41   * Mapping a <em>none</em> of type A to type B will simply return a none of type
42   * B if performed on a none of type A. Similarly, filtering will always fail on
43   * a <em>none</em>.
44   * <p>
45   * This class is often used as an alternative to <code>null</code> where
46   * <code>null</code> may be used to represent an optional value. There are
47   * however some situations where <code>null</code> may be a legitimate value,
48   * and that even though the option is defined, it still carries a
49   * <code>null</code> inside. Specifically, this will happen if a function is
50   * mapped across it returns null, as it is necessary to preserve the <a
51   * href=http://en.wikipedia.org/wiki/Functor>Functor composition law</a>. Note
52   * however, that this should be rare as functions that return <code>null</code>
53   * is a bad idea anyway. <b>Note</b> that if a function returns null to indicate
54   * optionality, it can be {@link io.atlassian.fugue.Options#lift(Function)
55   * lifted} into a partial function and then {@link #flatMap(Function) flat
56   * mapped} instead.
57   * <p>
58   * Note: while this class is public and abstract it does not expose a
59   * constructor as only the concrete internal subclasses are designed to be used.
60   *
61   * @param <A> the value type the option contains
62   * @since 1.0
63   */
64  public abstract class Option<A> implements Iterable<A>, Maybe<A>, Serializable {
65    private static final long serialVersionUID = 7849097310208471377L;
66  
67    /**
68     * Factory method for {@link io.atlassian.fugue.Option} instances.
69     *
70     * @param <A> the contained type
71     * @param a the value to hold
72     * @return a Some if the parameter is not null or a None if it is
73     */
74    public static <A> Option<A> option(final A a) {
75      return (a == null) ? Option.<A> none() : new Some<>(a);
76    }
77  
78    /**
79     * Factory method for Some instances.
80     *
81     * @param <A> the contained type
82     * @param value the value to hold, must not be null
83     * @return a Some if the parameter is not null
84     * @throws java.lang.NullPointerException if the parameter is null
85     */
86    public static <A> Option<A> some(final A value) {
87      requireNonNull(value);
88      return new Some<>(value);
89    }
90  
91    /**
92     * Factory method for None instances.
93     *
94     * @param <A> the held type
95     * @return a None
96     */
97    public static <A> Option<A> none() {
98      @SuppressWarnings("unchecked")
99      final Option<A> result = (Option<A>) None.NONE;
100     return result;
101   }
102 
103   /**
104    * Factory method for None instances where the type token is handy. Allows
105    * calling in-line where the type inferencer would otherwise complain.
106    *
107    * @param <A> the contained type
108    * @param type token of the right type, unused, only here for the type
109    * inferencer
110    * @return a None
111    */
112   public static <A> Option<A> none(final Class<A> type) {
113     return none();
114   }
115 
116   /**
117    * Predicate for filtering defined options only.
118    *
119    * @param <A> the contained type
120    * @return a {@link java.util.function.Predicate} that returns true only for
121    * defined options
122    */
123   public static <A> Predicate<Option<A>> defined() {
124     return Maybe::isDefined;
125   }
126 
127   /**
128    * Supplies None as required. Useful as the zero value for folds.
129    *
130    * @param <A> the contained type
131    * @return a {@link java.util.function.Supplier} of None instances
132    */
133   public static <A> Supplier<Option<A>> noneSupplier() {
134     return ofInstance(Option.<A> none());
135   }
136 
137   /**
138    * Factory method for {@link io.atlassian.fugue.Option} instances from
139    * {@link java.util.Optional} instances.
140    *
141    * @param <A> the contained type
142    * @return a Some if {@link java.util.Optional#isPresent()} or a None
143    * otherwise.
144    * @param optional a {@link java.util.Optional} object.
145    */
146   public static <A> Option<A> fromOptional(final Optional<A> optional) {
147     return option(optional.orElse(null));
148   }
149 
150   //
151   // ctors
152   //
153 
154   /** do not constructor */
155   Option() {}
156 
157   //
158   // abstract methods
159   //
160 
161   /**
162    * If this is a some value apply the some function, otherwise get the None
163    * value.
164    *
165    * @param <B> the result type
166    * @param none the supplier of the None type
167    * @param some the function to apply if this is a Some
168    * @return the appropriate value
169    */
170   public abstract <B> B fold(Supplier<? extends B> none, Function<? super A, ? extends B> some);
171 
172   //
173   // implementing Maybe
174   //
175 
176   /** {@inheritDoc} */
177   @Override public final <B extends A> A getOrElse(final B other) {
178     return getOr(Suppliers.<A> ofInstance(other));
179   }
180 
181   /** {@inheritDoc} */
182   @Override public final A getOr(final Supplier<? extends A> supplier) {
183     return fold(supplier, Functions.<A> identity());
184   }
185 
186   /** {@inheritDoc} */
187   @Deprecated @Override public final A getOrElse(final Supplier<? extends A> supplier) {
188     return fold(supplier, Functions.<A> identity());
189   }
190 
191   /** {@inheritDoc} */
192   @Override public final A getOrNull() {
193     return fold(Suppliers.<A> alwaysNull(), Functions.<A> identity());
194   }
195 
196   /**
197    * If this is a some, return the same some. Otherwise, return {@code orElse}.
198    *
199    * @param orElse option to return if this is none
200    * @return this or {@code orElse}
201    * @since 1.1
202    */
203   public final Option<A> orElse(final Option<? extends A> orElse) {
204     return orElse(ofInstance(orElse));
205   }
206 
207   /**
208    * If this is a some, return the same some. Otherwise, return value supplied
209    * by {@code orElse}.
210    *
211    * @param orElse supplier which provides the option to return if this is none
212    * @return this or value supplied by {@code orElse}
213    * @since 1.1
214    */
215   public final Option<A> orElse(final Supplier<? extends Option<? extends A>> orElse) {
216     @SuppressWarnings("unchecked")
217     // safe covariant cast
218     final Option<A> result = (Option<A>) fold(orElse, Options.toOption());
219     return result;
220   }
221 
222   /** {@inheritDoc} */
223   @Override public final boolean exists(final Predicate<? super A> p) {
224     requireNonNull(p);
225     return isDefined() && p.test(get());
226   }
227 
228   /** {@inheritDoc} */
229   @Override public final boolean forall(final Predicate<? super A> p) {
230     requireNonNull(p);
231     return isEmpty() || p.test(get());
232   }
233 
234   /** {@inheritDoc} */
235   @Override public final boolean isEmpty() {
236     return !isDefined();
237   }
238 
239   /** {@inheritDoc} */
240   @Override public final Iterator<A> iterator() {
241     return fold(ofInstance(Iterators.<A> emptyIterator()), Iterators::<A> singletonIterator);
242   }
243 
244   //
245   // stuff that can't be put on an interface without HKT
246   //
247 
248   /**
249    * Apply {@code f} to the value if defined.
250    * <p>
251    * Transforms to an option of the result type.
252    *
253    * @param <B> return type of {@code f}
254    * @param f function to apply to wrapped value
255    * @return new wrapped value
256    */
257   public final <B> Option<B> map(final Function<? super A, ? extends B> f) {
258     requireNonNull(f);
259     return isEmpty() ? Option.<B> none() : new Some<>(f.apply(get()));
260   }
261 
262   /**
263    * Apply {@code f} to the value if defined.
264    * <p>
265    * Transforms to an option of the result type.
266    *
267    * @param <B> return type of {@code f}
268    * @param f function to apply to wrapped value
269    * @return value returned from {@code f}
270    */
271   public final <B> Option<B> flatMap(final Function<? super A, ? extends Option<? extends B>> f) {
272     requireNonNull(f);
273     @SuppressWarnings("unchecked")
274     final Option<B> result = (Option<B>) fold(Option.<B> noneSupplier(), f);
275     return result;
276   }
277 
278   /**
279    * Returns this {@link io.atlassian.fugue.Option} if it is nonempty
280    * <strong>and</strong> applying the predicate to this option's value returns
281    * true. Otherwise, return {@link #none()}.
282    *
283    * @param p the predicate to test
284    * @return this option, or none
285    */
286   public final Option<A> filter(final Predicate<? super A> p) {
287     requireNonNull(p);
288     return (isEmpty() || p.test(get())) ? this : Option.<A> none();
289   }
290 
291   /**
292    * Creates an Either from this Option. Puts the contained value in a right if
293    * {@link #isDefined()} otherwise puts the supplier's value in a left.
294    *
295    * @param <X> the left type
296    * @param left the Supplier to evaluate and return if this is empty
297    * @return the content of this option if defined as a right, or the supplier's
298    * content as a left if not
299    * @see Option#toLeft
300    */
301   public final <X> Either<X, A> toRight(final Supplier<X> left) {
302     return isEmpty() ? Either.<X, A> left(left.get()) : Either.<X, A> right(get());
303   }
304 
305   /**
306    * Creates an Either from this Option. Puts the contained value in a left if
307    * {@link #isDefined()} otherwise puts the supplier's value in a right.
308    *
309    * @param <X> the right type
310    * @param right the Supplier to evaluate and return if this is empty
311    * @return the content of this option if defined as a left, or the supplier's
312    * content as a right if not defined.
313    * @see Option#toRight
314    */
315   public final <X> Either<A, X> toLeft(final Supplier<X> right) {
316     return isEmpty() ? Either.<A, X> right(right.get()) : Either.<A, X> left(get());
317   }
318 
319   /**
320    * Create an {@link java.util.Optional} from this option. Will throw a
321    * {@link java.lang.NullPointerException} if this option is defined and
322    * contains a null value.
323    *
324    * @return {@link java.util.Optional#of(Object)} with the value if defined and
325    * not null, {@link java.util.Optional#empty()} if not defined.
326    */
327   public abstract Optional<A> toOptional();
328 
329   /**
330    * Create a {@link java.util.stream.Stream} from this option.
331    *
332    * @return {@link java.util.stream.Stream#of(Object)} with the value if
333    * defined, {@link java.util.stream.Stream#empty()} if not defined.
334    * @since 4.5.0
335    */
336   public abstract Stream<A> toStream();
337 
338   /** {@inheritDoc} */
339   @Override public final int hashCode() {
340     return fold(NONE_HASH, SOME_HASH);
341   }
342 
343   /** {@inheritDoc} */
344   @Override public final boolean equals(final Object obj) {
345     if (this == obj) {
346       return true;
347     }
348     if ((obj == null) || !(obj instanceof Option<?>)) {
349       return false;
350     }
351     final Option<?> other = (Option<?>) obj;
352     return other.fold(isDefined() ? Suppliers.alwaysFalse() : Suppliers.alwaysTrue(), valuesEqual());
353   }
354 
355   /** {@inheritDoc} */
356   @Override public final String toString() {
357     return fold(NONE_STRING, SOME_STRING);
358   }
359 
360   //
361   // util methods
362   //
363 
364   private Function<Object, Boolean> valuesEqual() {
365     return obj -> isDefined() && Objects.equals(get(), obj);
366   }
367 
368   //
369   // static members
370   //
371 
372   private static final Supplier<String> NONE_STRING = ofInstance("none()");
373   private static final Supplier<Integer> NONE_HASH = ofInstance(31);
374 
375   private static final Function<Object, String> SOME_STRING = obj -> String.format("some(%s)", obj);
376   private static final Function<Object, Integer> SOME_HASH = Object::hashCode;
377 
378   //
379   // inner classes
380   //
381 
382   /**
383    * One of the big two actual implementation classes.
384    * 
385    * @since 4.2.0
386    */
387   static final class None extends Option<Object> {
388     private static final long serialVersionUID = -1978333494161467110L;
389 
390     private static final Option<Object> NONE = new None();
391 
392     @Override public <B> B fold(final Supplier<? extends B> none, final Function<? super Object, ? extends B> some) {
393       return none.get();
394     }
395 
396     @Override public Object get() {
397       throw new NoSuchElementException();
398     }
399 
400     @Override public boolean isDefined() {
401       return false;
402     }
403 
404     @Override public Object getOrError(final Supplier<String> err) {
405       throw new AssertionError(err.get());
406     }
407 
408     @Override public <X extends Throwable> Object getOrThrow(final Supplier<X> ifUndefined) throws X {
409       throw ifUndefined.get();
410     }
411 
412     @Deprecated @Override public void foreach(final Effect<? super Object> effect) {
413       this.forEach(effect);
414     }
415 
416     @Override public void forEach(final Consumer<? super Object> effect) {}
417 
418     @Override public Optional<Object> toOptional() {
419       return Optional.empty();
420     }
421 
422     @Override public Stream<Object> toStream() {
423       return Stream.empty();
424     }
425 
426     private Object readResolve() {
427       return None.NONE;
428     }
429   }
430 
431   /**
432    * One of the big two actual implementation classes.
433    */
434   static final class Some<A> extends Option<A> {
435     private static final long serialVersionUID = 5542513144209030852L;
436 
437     private final A value;
438 
439     private Some(final A value) {
440       this.value = value;
441     }
442 
443     @Override public <B> B fold(final Supplier<? extends B> none, final Function<? super A, ? extends B> f) {
444       return f.apply(value);
445     }
446 
447     @Override public A get() {
448       return value;
449     }
450 
451     @Override public boolean isDefined() {
452       return true;
453     }
454 
455     @Override public A getOrError(final Supplier<String> err) {
456       return get();
457     }
458 
459     @Override public <X extends Throwable> A getOrThrow(final Supplier<X> ifUndefined) throws X {
460       return get();
461     }
462 
463     @Deprecated @Override public void foreach(final Effect<? super A> effect) {
464       this.forEach(effect);
465     }
466 
467     @Override public void forEach(final Consumer<? super A> effect) {
468       effect.accept(value);
469     }
470 
471     @Override public Optional<A> toOptional() {
472       return Optional.of(value);
473     }
474 
475     @Override public Stream<A> toStream() {
476       return Stream.of(value);
477     }
478   }
479 
480   /**
481    * Backwards compatibility requires us to have a class Option$1 so we can
482    * deserialize it into Option$None.
483    *
484    * @since 4.2.0
485    */
486   @Deprecated private static final Serializable NONE = new Serializable() {
487     private static final long serialVersionUID = -1978333494161467110L;
488 
489     private Object readResolve() {
490       return None.NONE;
491     }
492   };
493 
494 }