001    package fj.data;
002    
003    import static fj.Bottom.error;
004    import fj.*;
005    import static fj.Function.*;
006    import static fj.Unit.unit;
007    import static fj.data.Array.array;
008    import static fj.data.List.cons;
009    import static fj.data.List.cons_;
010    
011    import java.util.Collection;
012    import java.util.Iterator;
013    
014    /**
015     * An optional value that may be none (no value) or some (a value). This type is a replacement for
016     * the use of <code>null</code> with better type checks.
017     *
018     * @version %build.number%<br>
019     *          <ul>
020     *          <li>$LastChangedRevision: 292 $</li>
021     *          <li>$LastChangedDate: 2010-01-17 13:11:13 +1000 (Sun, 17 Jan 2010) $</li>
022     *          </ul>
023     */
024    public abstract class Option<A> implements Iterable<A> {
025      private Option() {
026    
027      }
028    
029      /**
030       * Returns an iterator for this optional value. This method exists to permit the use in a <code>for</code>-each loop.
031       *
032       * @return A iterator for this optional value.
033       */
034      public Iterator<A> iterator() {
035        return toCollection().iterator();
036      }
037    
038      /**
039       * Returns the value from this optional value, or fails if there is no value.
040       *
041       * @return The value from this optional value, or fails if there is no value.
042       */
043      public abstract A some();
044    
045      /**
046       * Returns <code>true</code> if this optional value has a value, <code>false</code> otherwise.
047       *
048       * @return <code>true</code> if this optional value has a value, <code>false</code> otherwise.
049       */
050      public boolean isSome() {
051        return this instanceof Some;
052      }
053    
054      /**
055       * Returns <code>false</code> if this optional value has a value, <code>true</code> otherwise.
056       *
057       * @return <code>false</code> if this optional value has a value, <code>true</code> otherwise.
058       */
059      public boolean isNone() {
060        return this instanceof None;
061      }
062    
063      /**
064       * A first-class version of the isSome method.
065       *
066       * @return A function that returns true if a given optional value has a value, otherwise false.
067       */
068      public static <A> F<Option<A>, Boolean> isSome_() {
069        return new F<Option<A>, Boolean>() {
070          public Boolean f(final Option<A> a) {
071            return a.isSome();
072          }
073        };
074      }
075    
076      /**
077       * A first-class version of the isNone method.
078       *
079       * @return A function that returns false if a given optional value has a value, otherwise true.
080       */
081      public static <A> F<Option<A>, Boolean> isNone_() {
082        return new F<Option<A>, Boolean>() {
083          public Boolean f(final Option<A> a) {
084            return a.isNone();
085          }
086        };
087      }
088    
089      /**
090       * Performs a reduction on this optional value using the given arguments.
091       *
092       * @param b The value to return if this optional value has no value.
093       * @param f The function to apply to the value of this optional value.
094       * @return A reduction on this optional value.
095       */
096      public <B> B option(final B b, final F<A, B> f) {
097        return isSome() ? f.f(some()) : b;
098      }
099    
100      /**
101       * Performs a reduction on this optional value using the given arguments.
102       *
103       * @param b The value to return if this optional value has no value.
104       * @param f The function to apply to the value of this optional value.
105       * @return A reduction on this optional value.
106       */
107      public <B> B option(final P1<B> b, final F<A, B> f) {
108        return isSome() ? f.f(some()) : b._1();
109      }
110    
111      /**
112       * Returns the length of this optional value; 1 is there is a value, 0 otherwise.
113       *
114       * @return The length of this optional value; 1 is there is a value, 0 otherwise.
115       */
116      public int length() {
117        return isSome() ? 1 : 0;
118      }
119    
120      /**
121       * Returns the value of this optional value or the given argument.
122       *
123       * @param a The argument to return if this optiona value has no value.
124       * @return The value of this optional value or the given argument.
125       */
126      public A orSome(final P1<A> a) {
127        return isSome() ? some() : a._1();
128      }
129    
130      /**
131       * Returns the value of this optional value or the given argument.
132       *
133       * @param a The argument to return if this optiona value has no value.
134       * @return The value of this optional value or the given argument.
135       */
136      public A orSome(final A a) {
137        return isSome() ? some() : a;
138      }
139    
140      /**
141       * Returns the value of this optional value or fails with the given message.
142       *
143       * @param message The message to fail with if this optional value has no value.
144       * @return The value of this optional value if there there is one.
145       */
146      public A valueE(final P1<String> message) {
147        if(isSome())
148          return some();
149        else
150          throw error(message._1());
151      }
152    
153      /**
154       * Returns the value of this optional value or fails with the given message.
155       *
156       * @param message The message to fail with if this optional value has no value.
157       * @return The value of this optional value if there there is one.
158       */
159      public A valueE(final String message) {
160        if(isSome())
161          return some();
162        else
163          throw error(message);
164      }
165    
166      /**
167       * Maps the given function across this optional value.
168       *
169       * @param f The function to map across this optional value.
170       * @return A new optional value after the given function has been applied to its element.
171       */
172      public <B> Option<B> map(final F<A, B> f) {
173        return isSome() ? some(f.f(some())) : Option.<B>none();
174      }
175    
176      /**
177       * A first-class map function.
178       *
179       * @return A function that maps a given function across a given optional value.
180       */
181      public static <A, B> F<F<A, B>, F<Option<A>, Option<B>>> map() {
182        return curry(new F2<F<A, B>, Option<A>, Option<B>>() {
183          public Option<B> f(final F<A, B> abf, final Option<A> option) {
184            return option.map(abf);
185          }
186        });
187      }
188    
189      /**
190       * Performs a side-effect for the value of this optional value.
191       *
192       * @param f The side-effect to perform for the given element.
193       * @return The unit value.
194       */
195      public Unit foreach(final F<A, Unit> f) {
196        return isSome() ? f.f(some()) : unit();
197      }
198    
199      /**
200       * Performs a side-effect for the value of this optional value.
201       *
202       * @param f The side-effect to perform for the given element.
203       */
204      public void foreach(final Effect<A> f) {
205        if (isSome())
206          f.e(some());
207      }
208    
209      /**
210       * Filters elements from this optional value by returning only elements which produce
211       * <code>true</code> when the given function is applied to them.
212       *
213       * @param f The predicate function to filter on.
214       * @return A new optional value whose value matches the given predicate if it has one.
215       */
216      public Option<A> filter(final F<A, Boolean> f) {
217        return isSome() ? f.f(some()) ? this : Option.<A>none() : Option.<A>none();
218      }
219    
220      /**
221       * Binds the given function across the element of this optional value with a final join.
222       *
223       * @param f The function to apply to the element of this optional value.
224       * @return A new optional value after performing the map, then final join.
225       */
226      public <B> Option<B> bind(final F<A, Option<B>> f) {
227        return isSome() ? f.f(some()) : Option.<B>none();
228      }
229    
230      /**
231       * Binds the given function across the element of this optional value and the given optional value
232       * with a final join.
233       *
234       * @param ob A given optional value to bind the given function with.
235       * @param f  The function to apply to the element of this optional value and the given optional
236       *           value.
237       * @return A new optional value after performing the map, then final join.
238       */
239      public <B, C> Option<C> bind(final Option<B> ob, final F<A, F<B, C>> f) {
240        return ob.apply(map(f));
241      }
242    
243      /**
244       * Binds the given function across the element of this optional value and the given optional value
245       * with a final join.
246       *
247       * @param ob A given optional value to bind the given function with.
248       * @param oc A given optional value to bind the given function with.
249       * @param f  The function to apply to the element of this optional value and the given optional
250       *           value.
251       * @return A new optional value after performing the map, then final join.
252       */
253      public <B, C, D> Option<D> bind(final Option<B> ob, final Option<C> oc, final F<A, F<B, F<C, D>>> f) {
254        return oc.apply(bind(ob, f));
255      }
256    
257      /**
258       * Binds the given function across the element of this optional value and the given optional value
259       * with a final join.
260       *
261       * @param ob A given optional value to bind the given function with.
262       * @param oc A given optional value to bind the given function with.
263       * @param od A given optional value to bind the given function with.
264       * @param f  The function to apply to the element of this optional value and the given optional
265       *           value.
266       * @return A new optional value after performing the map, then final join.
267       */
268      public <B, C, D, E> Option<E> bind(final Option<B> ob, final Option<C> oc, final Option<D> od,
269                                         final F<A, F<B, F<C, F<D, E>>>> f) {
270        return od.apply(bind(ob, oc, f));
271      }
272    
273      /**
274       * Binds the given function across the element of this optional value and the given optional value
275       * with a final join.
276       *
277       * @param ob A given optional value to bind the given function with.
278       * @param oc A given optional value to bind the given function with.
279       * @param od A given optional value to bind the given function with.
280       * @param oe A given optional value to bind the given function with.
281       * @param f  The function to apply to the element of this optional value and the given optional
282       *           value.
283       * @return A new optional value after performing the map, then final join.
284       */
285      public <B, C, D, E, F$> Option<F$> bind(final Option<B> ob, final Option<C> oc, final Option<D> od,
286                                              final Option<E> oe, final F<A, F<B, F<C, F<D, F<E, F$>>>>> f) {
287        return oe.apply(bind(ob, oc, od, f));
288      }
289    
290      /**
291       * Binds the given function across the element of this optional value and the given optional value
292       * with a final join.
293       *
294       * @param ob A given optional value to bind the given function with.
295       * @param oc A given optional value to bind the given function with.
296       * @param od A given optional value to bind the given function with.
297       * @param oe A given optional value to bind the given function with.
298       * @param of A given optional value to bind the given function with.
299       * @param f  The function to apply to the element of this optional value and the given optional
300       *           value.
301       * @return A new optional value after performing the map, then final join.
302       */
303      public <B, C, D, E, F$, G> Option<G> bind(final Option<B> ob, final Option<C> oc, final Option<D> od,
304                                                final Option<E> oe, final Option<F$> of,
305                                                final F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>> f) {
306        return of.apply(bind(ob, oc, od, oe, f));
307      }
308    
309      /**
310       * Binds the given function across the element of this optional value and the given optional value
311       * with a final join.
312       *
313       * @param ob A given optional value to bind the given function with.
314       * @param oc A given optional value to bind the given function with.
315       * @param od A given optional value to bind the given function with.
316       * @param oe A given optional value to bind the given function with.
317       * @param of A given optional value to bind the given function with.
318       * @param og A given optional value to bind the given function with.
319       * @param f  The function to apply to the element of this optional value and the given optional
320       *           value.
321       * @return A new optional value after performing the map, then final join.
322       */
323      public <B, C, D, E, F$, G, H> Option<H> bind(final Option<B> ob, final Option<C> oc, final Option<D> od,
324                                                   final Option<E> oe, final Option<F$> of, final Option<G> og,
325                                                   final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>> f) {
326        return og.apply(bind(ob, oc, od, oe, of, f));
327      }
328    
329      /**
330       * Binds the given function across the element of this optional value and the given optional value
331       * with a final join.
332       *
333       * @param ob A given optional value to bind the given function with.
334       * @param oc A given optional value to bind the given function with.
335       * @param od A given optional value to bind the given function with.
336       * @param oe A given optional value to bind the given function with.
337       * @param of A given optional value to bind the given function with.
338       * @param og A given optional value to bind the given function with.
339       * @param oh A given optional value to bind the given function with.
340       * @param f  The function to apply to the element of this optional value and the given optional
341       *           value.
342       * @return A new optional value after performing the map, then final join.
343       */
344      public <B, C, D, E, F$, G, H, I> Option<I> bind(final Option<B> ob, final Option<C> oc, final Option<D> od,
345                                                      final Option<E> oe, final Option<F$> of, final Option<G> og,
346                                                      final Option<H> oh,
347                                                      final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>> f) {
348        return oh.apply(bind(ob, oc, od, oe, of, og, f));
349      }
350    
351      public <B> Option<P2<A,B>> bindProduct(final Option<B> ob) {
352        return bind(ob, P.<A,B>p2()); 
353      }
354    
355      public <B,C> Option<P3<A,B,C>> bindProduct(final Option<B> ob, final Option<C> oc) {
356        return bind(ob, oc, P.<A,B,C>p3());
357      }
358      
359      public <B,C,D> Option<P4<A,B,C,D>> bindProduct(final Option<B> ob, final Option<C> oc, final Option<D> od) {
360        return bind(ob, oc, od, P.<A, B, C, D>p4());
361      }
362      
363      public <B,C,D,E> Option<P5<A,B,C,D,E>> bindProduct(final Option<B> ob, final Option<C> oc, final Option<D> od,
364                                                         final Option<E> oe) {
365        return bind(ob, oc, od, oe, P.<A, B, C, D, E>p5());
366      }
367    
368      public <B,C,D,E,F$> Option<P6<A,B,C,D,E,F$>> bindProduct(final Option<B> ob, final Option<C> oc, final Option<D> od,
369                                                               final Option<E> oe, final Option<F$> of) {
370        return bind(ob, oc, od, oe, of, P.<A, B, C, D, E, F$>p6());
371      }
372    
373      public <B,C,D,E,F$,G> Option<P7<A,B,C,D,E,F$,G>> bindProduct(final Option<B> ob, final Option<C> oc,
374                                                                   final Option<D> od, final Option<E> oe,
375                                                                   final Option<F$> of, final Option<G> og) {
376        return bind(ob, oc, od, oe, of, og, P.<A, B, C, D, E, F$, G>p7());
377      }
378    
379      public <B,C,D,E,F$,G,H> Option<P8<A,B,C,D,E,F$,G,H>> bindProduct(final Option<B> ob, final Option<C> oc,
380                                                                       final Option<D> od, final Option<E> oe,
381                                                                       final Option<F$> of, final Option<G> og,
382                                                                       final Option<H> oh) {
383        return bind(ob, oc, od, oe, of, og, oh, P.<A,B,C,D,E,F$,G,H>p8());
384      }
385    
386      /**
387       * Performs a bind across the optional value, but ignores the element value in the function.
388       *
389       * @param o The optional value to apply in the final join.
390       * @return A new optional value after the final join.
391       */
392      public <B> Option<B> sequence(final Option<B> o) {
393        final F<A, Option<B>> c = constant(o);
394        return bind(c);
395      }
396    
397      /**
398       * Performs function application within an optional value (applicative functor pattern).
399       *
400       * @param of The optional value of functions to apply.
401       * @return A new optional value after applying the given optional value of functions through this
402       *         optional value.
403       */
404      public <B> Option<B> apply(final Option<F<A, B>> of) {
405        return of.bind(new F<F<A, B>, Option<B>>() {
406          public Option<B> f(final F<A, B> f) {
407            return map(new F<A, B>() {
408              public B f(final A a) {
409                return f.f(a);
410              }
411            });
412          }
413        });
414      }
415    
416      /**
417       * Returns this optional value if there is one, otherwise, returns the argument optional value.
418       *
419       * @param o The optional value to return if this optional value has no value.
420       * @return This optional value if there is one, otherwise, returns the argument optional value.
421       */
422      public Option<A> orElse(final P1<Option<A>> o) {
423        return isSome() ? this : o._1();
424      }
425    
426      /**
427       * Returns this optional value if there is one, otherwise, returns the argument optional value.
428       *
429       * @param o The optional value to return if this optional value has no value.
430       * @return This optional value if there is one, otherwise, returns the argument optional value.
431       */
432      public Option<A> orElse(final Option<A> o) {
433        return isSome() ? this : o;
434      }
435    
436      /**
437       * Returns an either projection of this optional value; the given argument in <code>Left</code> if
438       * no value, or the value in <code>Right</code>.
439       *
440       * @param x The value to return in left if this optional value has no value.
441       * @return An either projection of this optional value.
442       */
443      public <X> Either<X, A> toEither(final P1<X> x) {
444        return isSome() ? Either.<X, A>right(some()) : Either.<X, A>left(x._1());
445      }
446    
447      /**
448       * Returns an either projection of this optional value; the given argument in <code>Left</code> if
449       * no value, or the value in <code>Right</code>.
450       *
451       * @param x The value to return in left if this optional value has no value.
452       * @return An either projection of this optional value.
453       */
454      public <X> Either<X, A> toEither(final X x) {
455        return isSome() ? Either.<X, A>right(some()) : Either.<X, A>left(x);
456      }
457    
458      /**
459       * A first-class version of the toEither method.
460       *
461       * @return A function that returns an either projection of a given optional value, given a value to
462       *         return in left.
463       */
464      public static <A, X> F<Option<A>, F<X, Either<X, A>>> toEither() {
465        return curry(new F2<Option<A>, X, Either<X, A>>() {
466          public Either<X, A> f(final Option<A> a, final X x) {
467            return a.toEither(x);
468          }
469        });
470      }
471    
472      /**
473       * Returns a list projection of this optional value.
474       *
475       * @return A list projection of this optional value.
476       */
477      public List<A> toList() {
478        return isSome() ? cons(some(), List.<A>nil()) : List.<A>nil();
479      }
480    
481      /**
482       * Returns a stream projection of this optional value.
483       *
484       * @return A stream projection of this optional value.
485       */
486      public Stream<A> toStream() {
487        return isSome() ? Stream.<A>nil().cons(some()) : Stream.<A>nil();
488      }
489    
490      /**
491       * Returns an array projection of this optional value.
492       *
493       * @return An array projection of this optional value.
494       */
495      @SuppressWarnings({"unchecked"})
496      public Array<A> toArray() {
497        return isSome() ? array(some()) : Array.<A>empty();
498      }
499    
500      /**
501       * Returns an array projection of this optional value.
502       *
503       * @param c The class type of the array to return.
504       * @return An array projection of this optional value.
505       */
506      @SuppressWarnings({"unchecked"})
507      public Array<A> toArray(final java.lang.Class<A[]> c) {
508        if (isSome()) {
509          final A[] a = (A[]) java.lang.reflect.Array.newInstance(c.getComponentType(), 1);
510          a[0] = some();
511          return array(a);
512        } else
513          return array((A[]) java.lang.reflect.Array.newInstance(c.getComponentType(), 0));
514      }
515    
516      /**
517       * Returns the value from this optional value, or if there is no value, returns <code>null</code>.
518       * This is intended for interfacing with APIs that expect a <code>null</code> for non-existence.
519       *
520       * @return This optional value or <code>null</code> if there is no value.
521       */
522      public A toNull() {
523        return orSome((A) null);
524      }
525    
526      /**
527       * Returns <code>true</code> if this optional value has no value, or the predicate holds for the
528       * given predicate function, <code>false</code> otherwise.
529       *
530       * @param f the predicate function to test on the value of this optional value.
531       * @return <code>true</code> if this optional value has no value, or the predicate holds for the
532       *         given predicate function, <code>false</code> otherwise.
533       */
534      public boolean forall(final F<A, Boolean> f) {
535        return isNone() || f.f(some());
536      }
537    
538      /**
539       * Returns <code>true</code> is this optional value has a value and the given predicate function
540       * holds on that value, <code>false</code> otherwise.
541       *
542       * @param f the predicate function to test on the value of this optional value.
543       * @return <code>true</code> is this optional value has a value and the given predicate function
544       *         holds on that value, <code>false</code> otherwise.
545       */
546      public boolean exists(final F<A, Boolean> f) {
547        return isSome() && f.f(some());
548      }
549    
550      /**
551       * Projects an immutable collection of this optional value.
552       *
553       * @return An immutable collection of this optional value.
554       */
555      public Collection<A> toCollection() {
556        return toList().toCollection();
557      }
558    
559      private static final class None<A> extends Option<A> {
560        public A some() {
561          throw error("some on None");
562        }
563      }
564    
565      private static final class Some<A> extends Option<A> {
566        private final A a;
567    
568        Some(final A a) {
569          this.a = a;
570        }
571    
572        public A some() {
573          return a;
574        }
575      }
576    
577      public static <T> F<T, Option<T>> some_() {
578        return new F<T, Option<T>>() {
579          public Option<T> f(final T t) {
580            return some(t);
581          }
582        };
583      }
584    
585      /**
586       * Constructs an optional value that has a value of the given argument.
587       *
588       * @param t The value for the returned optional value.
589       * @return An optional value that has a value of the given argument.
590       */
591      public static <T> Option<T> some(final T t) {
592        return new Some<T>(t);
593      }
594    
595      /**
596       * Constructs an optional value that has no value.
597       *
598       * @return An optional value that has no value.
599       */
600      public static <T> Option<T> none() {
601        return new None<T>();
602      }
603    
604      /**
605       * Turns an unsafe nullable value into a safe optional value. If <code>t == null</code> then
606       * return none, otherwise, return the given value in some.
607       *
608       * @param t The unsafe nullable value.
609       * @return If <code>t == null</code> then return it in some, otherwise, return none.
610       */
611      public static <T> Option<T> fromNull(final T t) {
612        return t == null ? Option.<T>none() : some(t);
613      }
614    
615      /**
616       * Joins the given optional value of optional value using a bind operation.
617       *
618       * @param o The optional value of optional value to join.
619       * @return A new optional value that is the join of the given optional value.
620       */
621      public static <A> Option<A> join(final Option<Option<A>> o) {
622        final F<Option<A>, Option<A>> id = identity();
623        return o.bind(id);
624      }
625    
626      /**
627       * Sequence through the option monad.
628       *
629       * @param a The list of option to sequence.
630       * @return The option of list after sequencing.
631       */
632      public static <A> Option<List<A>> sequence(final List<Option<A>> a) {
633        return a.isEmpty() ?
634               some(List.<A>nil()) :
635               a.head().bind(new F<A, Option<List<A>>>() {
636                 public Option<List<A>> f(final A aa) {
637                   return sequence(a.tail()).map(cons_(aa));
638                 }
639               });
640      }
641    
642      /**
643       * Returns an optional value that has a value of the given argument, if the given predicate holds
644       * on that argument, otherwise, returns no value.
645       *
646       * @param f The predicate to test on the given argument.
647       * @param a The argument to test the predicate on and potentially use as the value of the returned
648       *          optional value.
649       * @return an optional value that has a value of the given argument, if the given predicate holds
650       *         on that argument, otherwise, returns no value.
651       */
652      public static <A> Option<A> iif(final F<A, Boolean> f, final A a) {
653        return f.f(a) ? some(a) : Option.<A>none();
654      }
655    
656      /**
657       * First-class version of the iif function.
658       *
659       * @return a function that returns an optional value that has a value of the given argument, if the given predicate
660       *         holds on that argument, or no value otherwise.
661       */
662      public static <A> F2<F<A, Boolean>, A, Option<A>> iif() {
663        return new F2<F<A, Boolean>, A, Option<A>>() {
664          public Option<A> f(final F<A, Boolean> p, final A a) {
665            return iif(p, a);
666          }
667        };
668      }
669    
670      /**
671       * Returns all the values in the given list.
672       *
673       * @param as The list of potential values to get actual values from.
674       * @return All the values in the given list.
675       */
676      public static <A> List<A> somes(final List<Option<A>> as) {
677        return as.filter(Option.<A>isSome_()).map(new F<Option<A>, A>() {
678          public A f(final Option<A> o) {
679            return o.some();
680          }
681        });
682      }
683    
684    
685      /**
686       * Returns all the values in the given stream.
687       *
688       * @param as The stream of potential values to get actual values from.
689       * @return All the values in the given stream.
690       */
691      public static <A> Stream<A> somes(final Stream<Option<A>> as) {
692        return as.filter(Option.<A>isSome_()).map(new F<Option<A>, A>() {
693          public A f(final Option<A> o) {
694            return o.some();
695          }
696        });
697      }
698    
699      /**
700       * Returns an optional non-empty string, or no value if the given string is empty.
701       *
702       * @param s A string to turn into an optional non-empty string.
703       * @return an optional non-empty string, or no value if the given string is empty.
704       */
705      public static Option<String> fromString(final String s) {
706        return fromNull(s).bind(new F<String, Option<String>>() {
707          public Option<String> f(final String s) {
708            final Option<String> none = none();
709            return s.length() == 0 ? none : some(s);
710          }
711        });
712      }
713    
714      /**
715       * Returns a function that transforms a string to an optional non-empty string,
716       * or no value if the string is empty.
717       *
718       * @return a function that transforms a string to an optional non-empty string,
719       *         or no value if the string is empty.
720       */
721      public static F<String, Option<String>> fromString() {
722        return new F<String, Option<String>>() {
723          public Option<String> f(final String s) {
724            return fromString(s);
725          }
726        };
727      }
728    
729      /**
730       * Returns a function that takes an optional value to a value or errors if there is no value.
731       *
732       * @return A function that takes an optional value to a value or errors if there is no value.
733       */
734      public static <A> F<Option<A>, A> fromSome() {
735        return new F<Option<A>, A>() {
736          public A f(final Option<A> option) {
737            return option.some();
738          }
739        };
740      }
741    
742      /**
743       * Promotes a function of arity-2 so that it operates over options.
744       *
745       * @param f A function to promote.
746       * @return The given function promoted to operate on options.
747       */
748      public static <A, B, C> F<Option<A>, F<Option<B>, Option<C>>> liftM2(final F<A, F<B, C>> f) {
749        return curry(new F2<Option<A>, Option<B>, Option<C>>() {
750          public Option<C> f(final Option<A> a, final Option<B> b) {
751            return a.bind(b, f);
752          }
753        });
754      }
755    
756      /**
757       * First-class bind function.
758       *
759       * @return A function that binds a given function across an option with a final join.
760       */
761      public static <A, B> F<F<A, Option<B>>, F<Option<A>, Option<B>>> bind() {
762        return curry(new F2<F<A, Option<B>>, Option<A>, Option<B>>() {
763          public Option<B> f(final F<A, Option<B>> f, final Option<A> a) {
764            return a.bind(f);
765          }
766        });
767      }
768    
769      /**
770       * First-class join function.
771       *
772       * @return A function that joins an Option of an Option to make a single Option.
773       */
774      public static <A> F<Option<Option<A>>, Option<A>> join() {
775        return new F<Option<Option<A>>, Option<A>>() {
776          public Option<A> f(final Option<Option<A>> option) {
777            return join(option);
778          }
779        };
780      }
781    
782    }