001 package fj.data; 002 003 import fj.Effect; 004 import fj.F; 005 import fj.F2; 006 import fj.P; 007 import fj.P1; 008 import fj.P2; 009 import fj.Unit; 010 import static fj.Function.*; 011 import static fj.P.p; 012 import static fj.P.p2; 013 import static fj.Unit.unit; 014 import static fj.data.List.iterableList; 015 import static fj.data.Option.none; 016 import static fj.data.Option.some; 017 018 import static java.lang.Math.min; 019 import static java.lang.System.arraycopy; 020 import java.util.AbstractCollection; 021 import java.util.Arrays; 022 import java.util.Collection; 023 import java.util.Iterator; 024 import java.util.NoSuchElementException; 025 026 /** 027 * Provides an interface to arrays. 028 * 029 * @version %build.number%<br> 030 * <ul> 031 * <li>$LastChangedRevision: 303 $</li> 032 * <li>$LastChangedDate: 2010-01-20 14:16:55 +1000 (Wed, 20 Jan 2010) $</li> 033 * </ul> 034 */ 035 public final class Array<A> implements Iterable<A> { 036 private final Object[] a; 037 038 @SuppressWarnings({"AssignmentToCollectionOrArrayFieldFromParameter"}) 039 private Array(final Object[] a) { 040 this.a = a; 041 } 042 043 /** 044 * Returns an iterator for this array. This method exists to permit the use in a <code>for</code>-each loop. 045 * 046 * @return A iterator for this array. 047 */ 048 public Iterator<A> iterator() { 049 return toCollection().iterator(); 050 } 051 052 /** 053 * Returns the element at the given index if it exists, fails otherwise. 054 * 055 * @param index The index at which to get the element to return. 056 * @return The element at the given index if it exists, fails otherwise. 057 */ 058 @SuppressWarnings("unchecked") 059 public A get(final int index) { 060 return (A) a[index]; 061 } 062 063 /** 064 * Sets the element at the given index to the given value. 065 * 066 * @param index The index at which to set the given value. 067 * @param a The value to set at the given index. 068 * @return The unit value. 069 */ 070 public Unit set(final int index, final A a) { 071 this.a[index] = a; 072 return unit(); 073 } 074 075 /** 076 * Returns the length of this array. 077 * 078 * @return The length of this array. 079 */ 080 public int length() { 081 return a.length; 082 } 083 084 public ImmutableProjection<A> immutable() { 085 return new ImmutableProjection<A>(this); 086 } 087 088 /** 089 * Returns <code>true</code> is this array is empty, <code>false</code> otherwise. 090 * 091 * @return <code>true</code> is this array is empty, <code>false</code> otherwise. 092 */ 093 public boolean isEmpty() { 094 return a.length == 0; 095 } 096 097 /** 098 * Returns <code>false</code> is this array is empty, <code>true</code> otherwise. 099 * 100 * @return <code>false</code> is this array is empty, <code>true</code> otherwise. 101 */ 102 public boolean isNotEmpty() { 103 return a.length != 0; 104 } 105 106 /** 107 * Returns a copy of the underlying primitive array. 108 * 109 * @param c A class for the returned array. 110 * @return A copy of the underlying primitive array. 111 */ 112 public A[] array(final Class<A[]> c) { 113 return Arrays.copyOf(a, a.length, c); 114 } 115 116 /** 117 * Returns a copy of the underlying primitive array. 118 * 119 * @return A copy of the underlying primitive array; 120 */ 121 public Object[] array() { 122 return Arrays.copyOf(a, a.length); 123 } 124 125 /** 126 * Returns an option projection of this array; <code>None</code> if empty, or the first element in 127 * <code>Some</code>. 128 * 129 * @return An option projection of this array. 130 */ 131 @SuppressWarnings("unchecked") 132 public Option<A> toOption() { 133 return a.length == 0 ? Option.<A>none() : some((A) a[0]); 134 } 135 136 /** 137 * Returns an either projection of this array; the given argument in <code>Left</code> if empty, 138 * or the first element in <code>Right</code>. 139 * 140 * @param x The value to return in left if this array is empty. 141 * @return An either projection of this array. 142 */ 143 @SuppressWarnings("unchecked") 144 public <X> Either<X, A> toEither(final P1<X> x) { 145 return a.length == 0 ? Either.<X, A>left(x._1()) : Either.<X, A>right((A) a[0]); 146 } 147 148 /** 149 * Returns a list projection of this array. 150 * 151 * @return A list projection of this array. 152 */ 153 @SuppressWarnings("unchecked") 154 public List<A> toList() { 155 List<A> x = List.nil(); 156 157 for (int i = a.length - 1; i >= 0; i--) { 158 x = x.cons((A) a[i]); 159 } 160 161 return x; 162 } 163 164 /** 165 * Returns a stream projection of this array. 166 * 167 * @return A stream projection of this array. 168 */ 169 @SuppressWarnings("unchecked") 170 public Stream<A> toStream() { 171 return Stream.unfold(new F<Integer, Option<P2<A, Integer>>>() { 172 public Option<P2<A, Integer>> f(final Integer o) { 173 return a.length > o ? some(p((A) a[o], o + 1)) 174 : Option.<P2<A, Integer>>none(); 175 } 176 }, 0); 177 } 178 179 /** 180 * Maps the given function across this array. 181 * 182 * @param f The function to map across this array. 183 * @return A new array after the given function has been applied to each element. 184 */ 185 @SuppressWarnings({"unchecked"}) 186 public <B> Array<B> map(final F<A, B> f) { 187 final Object[] bs = new Object[a.length]; 188 189 for (int i = 0; i < a.length; i++) { 190 bs[i] = f.f((A) a[i]); 191 } 192 193 return new Array<B>(bs); 194 } 195 196 /** 197 * Filters elements from this array by returning only elements which produce <code>true</code> 198 * when the given function is applied to them. 199 * 200 * @param f The predicate function to filter on. 201 * @return A new array whose elements all match the given predicate. 202 */ 203 @SuppressWarnings("unchecked") 204 public Array<A> filter(final F<A, Boolean> f) { 205 List<A> x = List.nil(); 206 207 for (int i = a.length - 1; i >= 0; i--) { 208 if (f.f((A) a[i])) 209 x = x.cons((A) a[i]); 210 } 211 212 return x.toArray(); 213 } 214 215 /** 216 * Performs a side-effect for each element of this array. 217 * 218 * @param f The side-effect to perform for the given element. 219 * @return The unit value. 220 */ 221 @SuppressWarnings("unchecked") 222 public Unit foreach(final F<A, Unit> f) { 223 for (final Object x : a) { 224 f.f((A) x); 225 } 226 227 return unit(); 228 } 229 230 /** 231 * Performs a side-effect for each element of this array. 232 * 233 * @param f The side-effect to perform for the given element. 234 */ 235 @SuppressWarnings("unchecked") 236 public void foreach(final Effect<A> f) { 237 for (final Object x : a) { 238 f.e((A) x); 239 } 240 } 241 242 /** 243 * Performs a right-fold reduction across this array. This function runs in constant stack space. 244 * 245 * @param f The function to apply on each element of the array. 246 * @param b The beginning value to start the application from. 247 * @return The final result after the right-fold reduction. 248 */ 249 @SuppressWarnings("unchecked") 250 public <B> B foldRight(final F<A, F<B, B>> f, final B b) { 251 B x = b; 252 253 for (int i = a.length - 1; i >= 0; i--) 254 x = f.f((A) a[i]).f(x); 255 256 return x; 257 } 258 259 /** 260 * Performs a right-fold reduction across this array. This function runs in constant stack space. 261 * 262 * @param f The function to apply on each element of the array. 263 * @param b The beginning value to start the application from. 264 * @return The final result after the right-fold reduction. 265 */ 266 public <B> B foldRight(final F2<A, B, B> f, final B b) { 267 return foldRight(curry(f), b); 268 } 269 270 /** 271 * Performs a left-fold reduction across this array. This function runs in constant space. 272 * 273 * @param f The function to apply on each element of the array. 274 * @param b The beginning value to start the application from. 275 * @return The final result after the left-fold reduction. 276 */ 277 @SuppressWarnings("unchecked") 278 public <B> B foldLeft(final F<B, F<A, B>> f, final B b) { 279 B x = b; 280 281 for (final Object aa : a) 282 x = f.f(x).f((A) aa); 283 284 return x; 285 } 286 287 /** 288 * Performs a left-fold reduction across this array. This function runs in constant space. 289 * 290 * @param f The function to apply on each element of the array. 291 * @param b The beginning value to start the application from. 292 * @return The final result after the left-fold reduction. 293 */ 294 public <B> B foldLeft(final F2<B, A, B> f, final B b) { 295 return foldLeft(curry(f), b); 296 } 297 298 /** 299 * Binds the given function across each element of this array with a final join. 300 * 301 * @param f The function to apply to each element of this array. 302 * @return A new array after performing the map, then final join. 303 */ 304 @SuppressWarnings({"unchecked"}) 305 public <B> Array<B> bind(final F<A, Array<B>> f) { 306 List<Array<B>> x = List.nil(); 307 int len = 0; 308 309 for (int i = a.length - 1; i >= 0; i--) { 310 final Array<B> bs = f.f((A) a[i]); 311 len = len + bs.length(); 312 x = x.cons(bs); 313 } 314 315 final Object[] bs = new Object[len]; 316 317 x.foreach(new F<Array<B>, Unit>() { 318 private int i; 319 320 public Unit f(final Array<B> x) { 321 arraycopy(x.a, 0, bs, i, x.a.length); 322 i = i + x.a.length; 323 return unit(); 324 } 325 }); 326 327 return new Array<B>(bs); 328 } 329 330 /** 331 * Performs a bind across each array element, but ignores the element value each time. 332 * 333 * @param bs The array to apply in the final join. 334 * @return A new array after the final join. 335 */ 336 public <B> Array<B> sequence(final Array<B> bs) { 337 final F<A, Array<B>> c = constant(bs); 338 return bind(c); 339 } 340 341 /** 342 * Binds the given function across each element of this array and the given array with a final 343 * join. 344 * 345 * @param sb A given array to bind the given function with. 346 * @param f The function to apply to each element of this array and the given array. 347 * @return A new array after performing the map, then final join. 348 */ 349 public <B, C> Array<C> bind(final Array<B> sb, final F<A, F<B, C>> f) { 350 return sb.apply(map(f)); 351 } 352 353 /** 354 * Binds the given function across each element of this array and the given array with a final 355 * join. 356 * 357 * @param sb A given array to bind the given function with. 358 * @param f The function to apply to each element of this array and the given array. 359 * @return A new array after performing the map, then final join. 360 */ 361 public <B, C> Array<C> bind(final Array<B> sb, final F2<A, B, C> f) { 362 return bind(sb, curry(f)); 363 } 364 365 /** 366 * Performs function application within an array (applicative functor pattern). 367 * 368 * @param lf The array of functions to apply. 369 * @return A new array after applying the given array of functions through this array. 370 */ 371 public <B> Array<B> apply(final Array<F<A, B>> lf) { 372 return lf.bind(new F<F<A, B>, Array<B>>() { 373 public Array<B> f(final F<A, B> f) { 374 return map(new F<A, B>() { 375 public B f(final A a) { 376 return f.f(a); 377 } 378 }); 379 } 380 }); 381 } 382 383 /** 384 * Reverse this array in constant stack space. 385 * 386 * @return A new array that is the reverse of this one. 387 */ 388 public Array<A> reverse() { 389 final Object[] x = new Object[a.length]; 390 391 for (int i = 0; i < a.length; i++) { 392 x[a.length - 1 - i] = a[i]; 393 } 394 395 return new Array<A>(x); 396 } 397 398 /** 399 * Appends the given array to this array. 400 * 401 * @param aas The array to append to this one. 402 * @return A new array that has appended the given array. 403 */ 404 public Array<A> append(final Array<A> aas) { 405 final Object[] x = new Object[a.length + aas.a.length]; 406 407 arraycopy(a, 0, x, 0, a.length); 408 arraycopy(aas.a, 0, x, a.length, aas.a.length); 409 410 return new Array<A>(x); 411 } 412 413 /** 414 * Returns an empty array. 415 * 416 * @return An empty array. 417 */ 418 public static <A> Array<A> empty() { 419 return new Array<A>(new Object[0]); 420 } 421 422 /** 423 * Constructs an array from the given elements. 424 * 425 * @param a The elements to construct the array with. 426 * @return A new array of the given elements. 427 */ 428 public static <A> Array<A> array(final A... a) { 429 return new Array<A>(a); 430 } 431 432 /** 433 * Unsafe package-private constructor. The elements of the given array must be assignable to the given type. 434 * 435 * @param a An array with elements of the given type. 436 * @return A wrapped array. 437 */ 438 static <A> Array<A> mkArray(final Object[] a) { 439 return new Array<A>(a); 440 } 441 442 /** 443 * Constructs a singleton array. 444 * 445 * @param a The element to put in the array. 446 * @return An array with the given single element. 447 */ 448 public static <A> Array<A> single(final A a) { 449 return new Array<A>(new Object[]{a}); 450 } 451 452 /** 453 * First-class wrapper function for arrays. 454 * 455 * @return A function that wraps a given array. 456 */ 457 public static <A> F<A[], Array<A>> wrap() { 458 return new F<A[], Array<A>>() { 459 public Array<A> f(final A[] as) { 460 return array(as); 461 } 462 }; 463 } 464 465 /** 466 * First-class map function for Arrays. 467 * 468 * @return A function that maps a given function across a given array. 469 */ 470 public static <A, B> F<F<A, B>, F<Array<A>, Array<B>>> map() { 471 return curry(new F2<F<A, B>, Array<A>, Array<B>>() { 472 public Array<B> f(final F<A, B> abf, final Array<A> array) { 473 return array.map(abf); 474 } 475 }); 476 } 477 478 /** 479 * Joins the given array of arrays using a bind operation. 480 * 481 * @param o The array of arrays to join. 482 * @return A new array that is the join of the given arrays. 483 */ 484 public static <A> Array<A> join(final Array<Array<A>> o) { 485 final F<Array<A>, Array<A>> id = identity(); 486 return o.bind(id); 487 } 488 489 /** 490 * A first-class version of join 491 * 492 * @return A function that joins a array of arrays using a bind operation. 493 */ 494 public static <A> F<Array<Array<A>>, Array<A>> join() { 495 return new F<Array<Array<A>>, Array<A>>() { 496 public Array<A> f(final Array<Array<A>> as) { 497 return join(as); 498 } 499 }; 500 } 501 502 /** 503 * Returns <code>true</code> if the predicate holds for all of the elements of this array, 504 * <code>false</code> otherwise (<code>true</code> for the empty array). 505 * 506 * @param f the predicate function to test on each element of this array. 507 * @return <code>true</code> if the predicate holds for all of the elements of this array, 508 * <code>false</code> otherwise. 509 */ 510 @SuppressWarnings("unchecked") 511 public boolean forall(final F<A, Boolean> f) { 512 for (final Object x : a) 513 if (!f.f((A) x)) 514 return false; 515 516 return true; 517 } 518 519 /** 520 * Returns <code>true</code> if the predicate holds for at least one of the elements of this 521 * array, <code>false</code> otherwise (<code>false</code> for the empty array). 522 * 523 * @param f the predicate function to test on the elements of this array. 524 * @return <code>true</code> if the predicate holds for at least one of the elements of this 525 * array. 526 */ 527 @SuppressWarnings("unchecked") 528 public boolean exists(final F<A, Boolean> f) { 529 for (final Object x : a) 530 if (f.f((A) x)) 531 return true; 532 533 return false; 534 } 535 536 /** 537 * Finds the first occurrence of an element that matches the given predicate or no value if no 538 * elements match. 539 * 540 * @param f The predicate function to test on elements of this array. 541 * @return The first occurrence of an element that matches the given predicate or no value if no 542 * elements match. 543 */ 544 @SuppressWarnings("unchecked") 545 public Option<A> find(final F<A, Boolean> f) { 546 for (final Object x : a) 547 if (f.f((A) x)) 548 return some((A) x); 549 550 return none(); 551 } 552 553 /** 554 * Returns an array of integers from the given <code>from</code> value (inclusive) to the given 555 * <code>to</code> value (exclusive). 556 * 557 * @param from The minimum value for the array (inclusive). 558 * @param to The maximum value for the array (exclusive). 559 * @return An array of integers from the given <code>from</code> value (inclusive) to the given 560 * <code>to</code> value (exclusive). 561 */ 562 public static Array<Integer> range(final int from, final int to) { 563 if (from >= to) 564 return Array.empty(); 565 else { 566 final Array<Integer> a = new Array<Integer>(new Integer[to - from]); 567 568 for (int i = from; i < to; i++) 569 a.set(i - from, i); 570 571 return a; 572 } 573 } 574 575 /** 576 * Zips this array with the given array using the given function to produce a new array. If this 577 * array and the given array have different lengths, then the longer array is normalised so this 578 * function never fails. 579 * 580 * @param bs The array to zip this array with. 581 * @param f The function to zip this array and the given array with. 582 * @return A new array with a length the same as the shortest of this array and the given array. 583 */ 584 public <B, C> Array<C> zipWith(final Array<B> bs, final F<A, F<B, C>> f) { 585 final int len = min(a.length, bs.length()); 586 final Array<C> x = new Array<C>(new Object[len]); 587 588 for (int i = 0; i < len; i++) { 589 x.set(i, f.f(get(i)).f(bs.get(i))); 590 } 591 592 return x; 593 } 594 595 /** 596 * Zips this array with the given array using the given function to produce a new array. If this 597 * array and the given array have different lengths, then the longer array is normalised so this 598 * function never fails. 599 * 600 * @param bs The array to zip this array with. 601 * @param f The function to zip this array and the given array with. 602 * @return A new array with a length the same as the shortest of this array and the given array. 603 */ 604 public <B, C> Array<C> zipWith(final Array<B> bs, final F2<A, B, C> f) { 605 return zipWith(bs, curry(f)); 606 } 607 608 /** 609 * Zips this array with the given array to produce an array of pairs. If this array and the given 610 * array have different lengths, then the longer array is normalised so this function never fails. 611 * 612 * @param bs The array to zip this array with. 613 * @return A new array with a length the same as the shortest of this array and the given array. 614 */ 615 public <B> Array<P2<A, B>> zip(final Array<B> bs) { 616 final F<A, F<B, P2<A, B>>> __2 = p2(); 617 return zipWith(bs, __2); 618 } 619 620 /** 621 * Zips this array with the index of its element as a pair. 622 * 623 * @return A new array with the same length as this array. 624 */ 625 public Array<P2<A, Integer>> zipIndex() { 626 return zipWith(range(0, length()), new F<A, F<Integer, P2<A, Integer>>>() { 627 public F<Integer, P2<A, Integer>> f(final A a) { 628 return new F<Integer, P2<A, Integer>>() { 629 public P2<A, Integer> f(final Integer i) { 630 return p(a, i); 631 } 632 }; 633 } 634 }); 635 } 636 637 /** 638 * Projects an immutable collection of this array. 639 * 640 * @return An immutable collection of this array. 641 */ 642 @SuppressWarnings("unchecked") 643 public Collection<A> toCollection() { 644 return new AbstractCollection<A>() { 645 public Iterator<A> iterator() { 646 return new Iterator<A>() { 647 private int i; 648 649 public boolean hasNext() { 650 return i < a.length; 651 } 652 653 public A next() { 654 if (i >= a.length) 655 throw new NoSuchElementException(); 656 else { 657 final A aa = (A) a[i]; 658 i++; 659 return aa; 660 } 661 } 662 663 public void remove() { 664 throw new UnsupportedOperationException(); 665 } 666 }; 667 } 668 669 public int size() { 670 return a.length; 671 } 672 }; 673 } 674 675 /** 676 * Takes the given iterable to an array. 677 * 678 * @param i The iterable to take to an array. 679 * @return An array from the given iterable. 680 */ 681 public static <A> Array<A> iterableArray(final Iterable<A> i) { 682 return iterableList(i).toArray(); 683 } 684 685 /** 686 * Transforms an array of pairs into an array of first components and an array of second components. 687 * 688 * @param xs The array of pairs to transform. 689 * @return An array of first components and an array of second components. 690 */ 691 @SuppressWarnings({"unchecked"}) 692 public static <A, B> P2<Array<A>, Array<B>> unzip(final Array<P2<A, B>> xs) { 693 final int len = xs.length(); 694 final Array<A> aa = new Array<A>(new Object[len]); 695 final Array<B> ab = new Array<B>(new Object[len]); 696 for (int i = len - 1; i >= 0; i--) { 697 final P2<A, B> p = xs.get(i); 698 aa.set(i, p._1()); 699 ab.set(i, p._2()); 700 } 701 return P.p(aa, ab); 702 } 703 704 /** 705 * Projects an array by providing only operations which do not mutate. 706 */ 707 public final class ImmutableProjection<A> implements Iterable<A> { 708 private final Array<A> a; 709 710 private ImmutableProjection(final Array<A> a) { 711 this.a = a; 712 } 713 714 /** 715 * Returns an iterator for this array. This method exists to permit the use in a <code>for</code>-each loop. 716 * 717 * @return A iterator for this array. 718 */ 719 public Iterator<A> iterator() { 720 return a.iterator(); 721 } 722 723 /** 724 * Returns the element at the given index if it exists, fails otherwise. 725 * 726 * @param index The index at which to get the element to return. 727 * @return The element at the given index if it exists, fails otherwise. 728 */ 729 public A get(final int index) { 730 return a.get(index); 731 } 732 733 /** 734 * Returns the length of this array. 735 * 736 * @return The length of this array. 737 */ 738 public int length() { 739 return a.length(); 740 } 741 742 /** 743 * Returns <code>true</code> is this array is empty, <code>false</code> otherwise. 744 * 745 * @return <code>true</code> is this array is empty, <code>false</code> otherwise. 746 */ 747 public boolean isEmpty() { 748 return a.isEmpty(); 749 } 750 751 /** 752 * Returns <code>false</code> is this array is empty, <code>true</code> otherwise. 753 * 754 * @return <code>false</code> is this array is empty, <code>true</code> otherwise. 755 */ 756 public boolean isNotEmpty() { 757 return a.isNotEmpty(); 758 } 759 760 /** 761 * Returns an option projection of this array; <code>None</code> if empty, or the first element 762 * in <code>Some</code>. 763 * 764 * @return An option projection of this array. 765 */ 766 public Option<A> toOption() { 767 return a.toOption(); 768 } 769 770 /** 771 * Returns an either projection of this array; the given argument in <code>Left</code> if empty, 772 * or the first element in <code>Right</code>. 773 * 774 * @param x The value to return in left if this array is empty. 775 * @return An either projection of this array. 776 */ 777 public <X> Either<X, A> toEither(final P1<X> x) { 778 return a.toEither(x); 779 } 780 781 /** 782 * Returns a list projection of this array. 783 * 784 * @return A list projection of this array. 785 */ 786 public List<A> toList() { 787 return a.toList(); 788 } 789 790 /** 791 * Returns a stream projection of this array. 792 * 793 * @return A stream projection of this array. 794 */ 795 public Stream<A> toStream() { 796 return a.toStream(); 797 } 798 799 /** 800 * Maps the given function across this array. 801 * 802 * @param f The function to map across this array. 803 * @return A new array after the given function has been applied to each element. 804 */ 805 public <B> Array<B> map(final F<A, B> f) { 806 return a.map(f); 807 } 808 809 /** 810 * Filters elements from this array by returning only elements which produce <code>true</code> 811 * when the given function is applied to them. 812 * 813 * @param f The predicate function to filter on. 814 * @return A new array whose elements all match the given predicate. 815 */ 816 public Array<A> filter(final F<A, Boolean> f) { 817 return a.filter(f); 818 } 819 820 /** 821 * Performs a side-effect for each element of this array. 822 * 823 * @param f The side-effect to perform for the given element. 824 * @return The unit value. 825 */ 826 public Unit foreach(final F<A, Unit> f) { 827 return a.foreach(f); 828 } 829 830 /** 831 * Performs a right-fold reduction across this array. This function uses O(length) stack space. 832 * 833 * @param f The function to apply on each element of the array. 834 * @param b The beginning value to start the application from. 835 * @return The final result after the right-fold reduction. 836 */ 837 public <B> B foldRight(final F<A, F<B, B>> f, final B b) { 838 return a.foldRight(f, b); 839 } 840 841 /** 842 * Performs a left-fold reduction across this array. This function runs in constant space. 843 * 844 * @param f The function to apply on each element of the array. 845 * @param b The beginning value to start the application from. 846 * @return The final result after the left-fold reduction. 847 */ 848 public <B> B foldLeft(final F<B, F<A, B>> f, final B b) { 849 return a.foldLeft(f, b); 850 } 851 852 /** 853 * Binds the given function across each element of this array with a final join. 854 * 855 * @param f The function to apply to each element of this array. 856 * @return A new array after performing the map, then final join. 857 */ 858 public <B> Array<B> bind(final F<A, Array<B>> f) { 859 return a.bind(f); 860 } 861 862 /** 863 * Performs a bind across each array element, but ignores the element value each time. 864 * 865 * @param bs The array to apply in the final join. 866 * @return A new array after the final join. 867 */ 868 public <B> Array<B> sequence(final Array<B> bs) { 869 return a.sequence(bs); 870 } 871 872 /** 873 * Performs function application within an array (applicative functor pattern). 874 * 875 * @param lf The array of functions to apply. 876 * @return A new array after applying the given array of functions through this array. 877 */ 878 public <B> Array<B> apply(final Array<F<A, B>> lf) { 879 return a.apply(lf); 880 } 881 882 /** 883 * Reverse this array in constant stack space. 884 * 885 * @return A new array that is the reverse of this one. 886 */ 887 public Array<A> reverse() { 888 return a.reverse(); 889 } 890 891 /** 892 * Appends the given array to this array. 893 * 894 * @param aas The array to append to this one. 895 * @return A new array that has appended the given array. 896 */ 897 public Array<A> append(final Array<A> aas) { 898 return a.append(aas); 899 } 900 901 /** 902 * Projects an immutable collection of this array. 903 * 904 * @return An immutable collection of this array. 905 */ 906 public Collection<A> toCollection() { 907 return a.toCollection(); 908 } 909 } 910 }