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 }