PageRenderTime 57ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/ainotebook/planetai/src/flj/List.java

http://ainotebook.googlecode.com/
Java | 1713 lines | 755 code | 175 blank | 783 comment | 62 complexity | 0f0b0288c298c79cd927231b14f1e1bf MD5 | raw file
Possible License(s): GPL-2.0, Zlib, LGPL-2.1, BSD-3-Clause, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. package flj;
  2. import java.util.AbstractCollection;
  3. import java.util.Collection;
  4. import java.util.Iterator;
  5. import java.util.NoSuchElementException;
  6. /**
  7. * Provides an in-memory, immutable, singly linked list.
  8. *
  9. * @version 2.20<br>
  10. * <ul>
  11. * <li>$LastChangedRevision: 179 $</li>
  12. * <li>$LastChangedDate: 2009-06-28 05:39:00 +1000 (Sun, 28 Jun 2009) $</li>
  13. * </ul>
  14. */
  15. public abstract class List<A> implements Iterable<A> {
  16. private List() {
  17. }
  18. /**
  19. * Returns an iterator for this list. This method exists to permit the use in a <code>for</code>-each loop.
  20. *
  21. * @return A iterator for this list.
  22. */
  23. public Iterator<A> iterator() {
  24. return toCollection().iterator();
  25. }
  26. /**
  27. * The first element of the linked list or fails for the empty list.
  28. *
  29. * @return The first element of the linked list or fails for the empty list.
  30. */
  31. public abstract A head();
  32. /**
  33. * The list without the first element or fails for the empty list.
  34. *
  35. * @return The list without the first element or fails for the empty list.
  36. */
  37. public abstract List<A> tail();
  38. /**
  39. * The length of this list.
  40. *
  41. * @return The length of this list.
  42. */
  43. public int length() {
  44. return foldLeft(new F<Integer, F<A, Integer>>() {
  45. public F<A, Integer> f(final Integer i) {
  46. return new F<A, Integer>() {
  47. public Integer f(final A a) {
  48. return i + 1;
  49. }
  50. };
  51. }
  52. }, 0);
  53. }
  54. /**
  55. * Returns <code>true</code> if this list is empty, <code>false</code> otherwise.
  56. *
  57. * @return <code>true</code> if this list is empty, <code>false</code> otherwise.
  58. */
  59. public boolean isEmpty() {
  60. return this instanceof Nil;
  61. }
  62. /**
  63. * Returns <code>false</code> if this list is empty, <code>true</code> otherwise.
  64. *
  65. * @return <code>false</code> if this list is empty, <code>true</code> otherwise.
  66. */
  67. public boolean isNotEmpty() {
  68. return this instanceof Cons;
  69. }
  70. /**
  71. * Performs a reduction on this list using the given arguments.
  72. *
  73. * @param nil The value to return if this list is empty.
  74. * @param cons The function to apply to the head and tail of this list if it is not empty.
  75. * @return A reduction on this list.
  76. */
  77. public <B> B list(final B nil, final F<A, F<List<A>, B>> cons) {
  78. return isEmpty() ? nil : cons.f(head()).f(tail());
  79. }
  80. /**
  81. * Returns the head of this list if there is one or the given argument if this list is empty.
  82. *
  83. * @param a The argument to return if this list is empty.
  84. * @return The head of this list if there is one or the given argument if this list is empty.
  85. */
  86. public A orHead(final P1<A> a) {
  87. return isEmpty() ? a._1() : head();
  88. }
  89. /**
  90. * Returns the tail of this list if there is one or the given argument if this list is empty.
  91. *
  92. * @param as The argument to return if this list is empty.
  93. * @return The tail of this list if there is one or the given argument if this list is empty.
  94. */
  95. public List<A> orTail(final P1<List<A>> as) {
  96. return isEmpty() ? as._1() : tail();
  97. }
  98. /**
  99. * Returns an option projection of this list; <code>None</code> if empty, or the first element in
  100. * <code>Some</code>.
  101. *
  102. * @return An option projection of this list.
  103. */
  104. public Option<A> toOption() {
  105. return isEmpty() ? Option.<A>none() : Option.some(head());
  106. }
  107. /**
  108. * Returns an either projection of this list; the given argument in <code>Left</code> if empty, or
  109. * the first element in <code>Right</code>.
  110. *
  111. * @param x The value to return in left if this list is empty.
  112. * @return An either projection of this list.
  113. */
  114. public <X> Either<X, A> toEither(final P1<X> x) {
  115. return isEmpty() ? Either.<X, A>left(x._1()) : Either.<X, A>right(head());
  116. }
  117. /**
  118. * Returns a stream projection of this list.
  119. *
  120. * @return A stream projection of this list.
  121. */
  122. public Stream<A> toStream() {
  123. final Stream<A> nil = Stream.nil();
  124. return foldRight(new F<A, F<Stream<A>, Stream<A>>>() {
  125. public F<Stream<A>, Stream<A>> f(final A a) {
  126. return new F<Stream<A>, Stream<A>>() {
  127. public Stream<A> f(final Stream<A> as) {
  128. return as.cons(a);
  129. }
  130. };
  131. }
  132. }, nil);
  133. }
  134. /**
  135. * Returns a array projection of this list.
  136. *
  137. * @return A array projection of this list.
  138. */
  139. @SuppressWarnings({"unchecked"})
  140. public Array<A> toArray() {
  141. final Object[] a = new Object[length()];
  142. List<A> x = this;
  143. for (int i = 0; i < length(); i++) {
  144. a[i] = x.head();
  145. x = x.tail();
  146. }
  147. return Array.mkArray(a);
  148. }
  149. /**
  150. * Returns a array projection of this list.
  151. *
  152. * @param c The class type of the array to return.
  153. * @return A array projection of this list.
  154. */
  155. @SuppressWarnings({"unchecked"})
  156. public Array<A> toArray(final Class<A[]> c) {
  157. final A[] a = (A[]) java.lang.reflect.Array.newInstance(c.getComponentType(), length());
  158. List<A> x = this;
  159. for (int i = 0; i < length(); i++) {
  160. a[i] = x.head();
  161. x = x.tail();
  162. }
  163. return Array.array(a);
  164. }
  165. /**
  166. * Prepends (cons) the given element to this list to product a new list.
  167. *
  168. * @param a The element to prepend.
  169. * @return A new list with the given element at the head.
  170. */
  171. public List<A> cons(final A a) {
  172. return new Cons<A>(a, this);
  173. }
  174. /**
  175. * Prepends (cons) the given element to this list to product a new list. This method is added to prevent conflict with
  176. * overloads.
  177. *
  178. * @param a The element to prepend.
  179. * @return A new list with the given element at the head.
  180. */
  181. public List<A> conss(final A a) {
  182. return new Cons<A>(a, this);
  183. }
  184. /**
  185. * Maps the given function across this list.
  186. *
  187. * @param f The function to map across this list.
  188. * @return A new list after the given function has been applied to each element.
  189. */
  190. public <B> List<B> map(final F<A, B> f) {
  191. final Buffer<B> bs = Buffer.empty();
  192. for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
  193. bs.snoc(f.f(xs.head()));
  194. }
  195. return bs.toList();
  196. }
  197. /**
  198. * Performs a side-effect for each element of this list.
  199. *
  200. * @param f The side-effect to perform for the given element.
  201. * @return The unit value.
  202. */
  203. public Unit foreach(final F<A, Unit> f) {
  204. for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
  205. f.f(xs.head());
  206. }
  207. return Unit.unit();
  208. }
  209. /**
  210. * Performs a side-effect for each element of this list.
  211. *
  212. * @param f The side-effect to perform for the given element.
  213. */
  214. public void foreach(final Effect<A> f) {
  215. for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
  216. f.e(xs.head());
  217. }
  218. }
  219. /**
  220. * Filters elements from this list by returning only elements which produce <code>true</code> when
  221. * the given function is applied to them.
  222. *
  223. * @param f The predicate function to filter on.
  224. * @return A new list whose elements all match the given predicate.
  225. */
  226. public List<A> filter(final F<A, Boolean> f) {
  227. final Buffer<A> b = Buffer.empty();
  228. for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
  229. final A h = xs.head();
  230. if (f.f(h)) {
  231. b.snoc(h);
  232. }
  233. }
  234. return b.toList();
  235. }
  236. /**
  237. * Filters elements from this list by returning only elements which produce <code>false</code> when
  238. * the given function is applied to them.
  239. *
  240. * @param f The predicate function to filter on.
  241. * @return A new list whose elements do not match the given predicate.
  242. */
  243. public List<A> removeAll(final F<A, Boolean> f) {
  244. return filter(Function.compose(Booleans.not, f));
  245. }
  246. /**
  247. * Removes the first element that equals the given object.
  248. * To remove all matches, use <code>removeAll(e.eq(a))</code>
  249. *
  250. * @param a The element to remove
  251. * @param e An <code>Equals</code> instance for the element's type.
  252. * @return A new list whose elements do not match the given predicate.
  253. */
  254. public List<A> delete(final A a, final Equal<A> e) {
  255. final P2<List<A>, List<A>> p = span(Function.compose(Booleans.not, e.eq(a)));
  256. return p._2().isEmpty() ? p._1() : p._1().append(p._2().tail());
  257. }
  258. /**
  259. * Returns the first elements of the head of this list that match the given predicate function.
  260. *
  261. * @param f The predicate function to apply on this list until it finds an element that does not
  262. * hold, or the list is exhausted.
  263. * @return The first elements of the head of this list that match the given predicate function.
  264. */
  265. public List<A> takeWhile(final F<A, Boolean> f) {
  266. final Buffer<A> b = Buffer.empty();
  267. boolean taking = true;
  268. for (List<A> xs = this; xs.isNotEmpty() && taking; xs = xs.tail()) {
  269. final A h = xs.head();
  270. if (f.f(h)) {
  271. b.snoc(h);
  272. } else {
  273. taking = false;
  274. }
  275. }
  276. return b.toList();
  277. }
  278. /**
  279. * Removes elements from the head of this list that do not match the given predicate function
  280. * until an element is found that does match or the list is exhausted.
  281. *
  282. * @param f The predicate function to apply through this list.
  283. * @return The list whose first element does not match the given predicate function.
  284. */
  285. public List<A> dropWhile(final F<A, Boolean> f) {
  286. List<A> xs;
  287. //noinspection StatementWithEmptyBody
  288. for (xs = this; xs.isNotEmpty() && f.f(xs.head()); xs = xs.tail()) ;
  289. return xs;
  290. }
  291. /**
  292. * Returns a tuple where the first element is the longest prefix of this list that satisfies
  293. * the given predicate and the second element is the remainder of the list.
  294. *
  295. * @param p A predicate to be satisfied by a prefix of this list.
  296. * @return A tuple where the first element is the longest prefix of this list that satisfies
  297. * the given predicate and the second element is the remainder of the list.
  298. */
  299. public P2<List<A>, List<A>> span(final F<A, Boolean> p) {
  300. final Buffer<A> b = Buffer.empty();
  301. for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
  302. if (p.f(xs.head()))
  303. b.snoc(xs.head());
  304. else
  305. return P.p(b.toList(), xs);
  306. }
  307. return P.p(b.toList(), List.<A>nil());
  308. }
  309. /**
  310. * Returns a tuple where the first element is the longest prefix of this list that does not satisfy
  311. * the given predicate and the second element is the remainder of the list.
  312. *
  313. * @param p A predicate for an element to not satisfy by a prefix of this list.
  314. * @return A tuple where the first element is the longest prefix of this list that does not satisfy
  315. * the given predicate and the second element is the remainder of the list.
  316. */
  317. public P2<List<A>, List<A>> breakk(final F<A, Boolean> p) {
  318. return span(new F<A, Boolean>() {
  319. public Boolean f(final A a) {
  320. return !p.f(a);
  321. }
  322. });
  323. }
  324. /**
  325. * Groups elements according to the given equality implementation.
  326. *
  327. * @param e The equality implementation for the elements.
  328. * @return A list of grouped elements.
  329. */
  330. public List<List<A>> group(final Equal<A> e) {
  331. if (isEmpty())
  332. return nil();
  333. else {
  334. final P2<List<A>, List<A>> z = tail().span(e.eq(head()));
  335. return cons(z._1().cons(head()), z._2().group(e));
  336. }
  337. }
  338. /**
  339. * Binds the given function across each element of this list with a final join.
  340. *
  341. * @param f The function to apply to each element of this list.
  342. * @return A new list after performing the map, then final join.
  343. */
  344. public <B> List<B> bind(final F<A, List<B>> f) {
  345. final Buffer<B> b = Buffer.empty();
  346. for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
  347. b.append(f.f(xs.head()));
  348. }
  349. return b.toList();
  350. }
  351. /**
  352. * Binds the given function across each element of this list and the given list with a final
  353. * join.
  354. *
  355. * @param lb A given list to bind the given function with.
  356. * @param f The function to apply to each element of this list and the given list.
  357. * @return A new list after performing the map, then final join.
  358. */
  359. public <B, C> List<C> bind(final List<B> lb, final F<A, F<B, C>> f) {
  360. return lb.apply(map(f));
  361. }
  362. /**
  363. * Binds the given function across each element of this list and the given list with a final
  364. * join.
  365. *
  366. * @param lb A given list to bind the given function with.
  367. * @param f The function to apply to each element of this list and the given list.
  368. * @return A new list after performing the map, then final join.
  369. */
  370. public <B, C> List<C> bind(final List<B> lb, final F2<A, B, C> f) {
  371. return bind(lb, Function.curry(f));
  372. }
  373. /**
  374. * Promotes the given function of arity-2 to a function on lists.
  375. *
  376. * @param f The functio to promote to a function on lists.
  377. * @return The given function, promoted to operate on lists.
  378. */
  379. public static <A, B, C> F<List<A>, F<List<B>, List<C>>> liftM2(final F<A, F<B, C>> f) {
  380. return Function.curry(new F2<List<A>, List<B>, List<C>>() {
  381. public List<C> f(final List<A> as, final List<B> bs) {
  382. return as.bind(bs, f);
  383. }
  384. });
  385. }
  386. /**
  387. * Binds the given function across each element of this list and the given lists with a final
  388. * join.
  389. *
  390. * @param lb A given list to bind the given function with.
  391. * @param lc A given list to bind the given function with.
  392. * @param f The function to apply to each element of this list and the given lists.
  393. * @return A new list after performing the map, then final join.
  394. */
  395. public <B, C, D> List<D> bind(final List<B> lb, final List<C> lc, final F<A, F<B, F<C, D>>> f) {
  396. return lc.apply(bind(lb, f));
  397. }
  398. /**
  399. * Binds the given function across each element of this list and the given lists with a final
  400. * join.
  401. *
  402. * @param lb A given list to bind the given function with.
  403. * @param lc A given list to bind the given function with.
  404. * @param ld A given list to bind the given function with.
  405. * @param f The function to apply to each element of this list and the given lists.
  406. * @return A new list after performing the map, then final join.
  407. */
  408. public <B, C, D, E> List<E> bind(final List<B> lb, final List<C> lc, final List<D> ld,
  409. final F<A, F<B, F<C, F<D, E>>>> f) {
  410. return ld.apply(bind(lb, lc, f));
  411. }
  412. /**
  413. * Binds the given function across each element of this list and the given lists with a final
  414. * join.
  415. *
  416. * @param lb A given list to bind the given function with.
  417. * @param lc A given list to bind the given function with.
  418. * @param ld A given list to bind the given function with.
  419. * @param le A given list to bind the given function with.
  420. * @param f The function to apply to each element of this list and the given lists.
  421. * @return A new list after performing the map, then final join.
  422. */
  423. public <B, C, D, E, F$> List<F$> bind(final List<B> lb, final List<C> lc, final List<D> ld, final List<E> le,
  424. final F<A, F<B, F<C, F<D, F<E, F$>>>>> f) {
  425. return le.apply(bind(lb, lc, ld, f));
  426. }
  427. /**
  428. * Binds the given function across each element of this list and the given lists with a final
  429. * join.
  430. *
  431. * @param lb A given list to bind the given function with.
  432. * @param lc A given list to bind the given function with.
  433. * @param ld A given list to bind the given function with.
  434. * @param le A given list to bind the given function with.
  435. * @param lf A given list to bind the given function with.
  436. * @param f The function to apply to each element of this list and the given lists.
  437. * @return A new list after performing the map, then final join.
  438. */
  439. public <B, C, D, E, F$, G> List<G> bind(final List<B> lb, final List<C> lc, final List<D> ld, final List<E> le,
  440. final List<F$> lf, final F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>> f) {
  441. return lf.apply(bind(lb, lc, ld, le, f));
  442. }
  443. /**
  444. * Binds the given function across each element of this list and the given lists with a final
  445. * join.
  446. *
  447. * @param lb A given list to bind the given function with.
  448. * @param lc A given list to bind the given function with.
  449. * @param ld A given list to bind the given function with.
  450. * @param le A given list to bind the given function with.
  451. * @param lf A given list to bind the given function with.
  452. * @param lg A given list to bind the given function with.
  453. * @param f The function to apply to each element of this list and the given lists.
  454. * @return A new list after performing the map, then final join.
  455. */
  456. public <B, C, D, E, F$, G, H> List<H> bind(final List<B> lb, final List<C> lc, final List<D> ld, final List<E> le,
  457. final List<F$> lf, final List<G> lg,
  458. final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>> f) {
  459. return lg.apply(bind(lb, lc, ld, le, lf, f));
  460. }
  461. /**
  462. * Binds the given function across each element of this list and the given lists with a final
  463. * join.
  464. *
  465. * @param lb A given list to bind the given function with.
  466. * @param lc A given list to bind the given function with.
  467. * @param ld A given list to bind the given function with.
  468. * @param le A given list to bind the given function with.
  469. * @param lf A given list to bind the given function with.
  470. * @param lg A given list to bind the given function with.
  471. * @param lh A given list to bind the given function with.
  472. * @param f The function to apply to each element of this list and the given lists.
  473. * @return A new list after performing the map, then final join.
  474. */
  475. public <B, C, D, E, F$, G, H, I> List<I> bind(final List<B> lb, final List<C> lc, final List<D> ld, final List<E> le,
  476. final List<F$> lf, final List<G> lg, final List<H> lh,
  477. final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>> f) {
  478. return lh.apply(bind(lb, lc, ld, le, lf, lg, f));
  479. }
  480. /**
  481. * Performs a bind across each list element, but ignores the element value each time.
  482. *
  483. * @param bs The list to apply in the final join.
  484. * @return A new list after the final join.
  485. */
  486. public <B> List<B> sequence(final List<B> bs) {
  487. final F<A, List<B>> c = Function.constant(bs);
  488. return bind(c);
  489. }
  490. /**
  491. * Performs function application within a list (applicative functor pattern).
  492. *
  493. * @param lf The list of functions to apply.
  494. * @return A new list after applying the given list of functions through this list.
  495. */
  496. public <B> List<B> apply(final List<F<A, B>> lf) {
  497. return lf.bind(new F<F<A, B>, List<B>>() {
  498. public List<B> f(final F<A, B> f) {
  499. return map(f);
  500. }
  501. });
  502. }
  503. /**
  504. * Appends the given list to this list.
  505. *
  506. * @param as The list to append to this one.
  507. * @return A new list that has appended the given list.
  508. */
  509. public List<A> append(final List<A> as) {
  510. return Buffer.fromList(this).append(as).toList();
  511. }
  512. /**
  513. * Performs a right-fold reduction across this list. This function uses O(length) stack space.
  514. *
  515. * @param f The function to apply on each element of the list.
  516. * @param b The beginning value to start the application from.
  517. * @return The final result after the right-fold reduction.
  518. */
  519. public <B> B foldRight(final F<A, F<B, B>> f, final B b) {
  520. return isEmpty() ? b : f.f(head()).f(tail().foldRight(f, b));
  521. }
  522. /**
  523. * Performs a right-fold reduction across this list. This function uses O(length) stack space.
  524. *
  525. * @param f The function to apply on each element of the list.
  526. * @param b The beginning value to start the application from.
  527. * @return The final result after the right-fold reduction.
  528. */
  529. public <B> B foldRight(final F2<A, B, B> f, final B b) {
  530. return foldRight(Function.curry(f), b);
  531. }
  532. /**
  533. * Performs a left-fold reduction across this list. This function runs in constant space.
  534. *
  535. * @param f The function to apply on each element of the list.
  536. * @param b The beginning value to start the application from.
  537. * @return The final result after the left-fold reduction.
  538. */
  539. public <B> B foldLeft(final F<B, F<A, B>> f, final B b) {
  540. B x = b;
  541. for (List<A> xs = this; !xs.isEmpty(); xs = xs.tail()) {
  542. x = f.f(x).f(xs.head());
  543. }
  544. return x;
  545. }
  546. /**
  547. * Performs a left-fold reduction across this list. This function runs in constant space.
  548. *
  549. * @param f The function to apply on each element of the list.
  550. * @param b The beginning value to start the application from.
  551. * @return The final result after the left-fold reduction.
  552. */
  553. public <B> B foldLeft(final F2<B, A, B> f, final B b) {
  554. return foldLeft(Function.curry(f), b);
  555. }
  556. /**
  557. * Takes the first 2 elements of the list and applies the function to them,
  558. * then applies the function to the result and the third element and so on.
  559. *
  560. * @param f The function to apply on each element of the list.
  561. * @return The final result after the left-fold reduction.
  562. */
  563. public A foldLeft1(final F2<A, A, A> f) {
  564. return foldLeft1(Function.curry(f));
  565. }
  566. /**
  567. * Takes the first 2 elements of the list and applies the function to them,
  568. * then applies the function to the result and the third element and so on.
  569. *
  570. * @param f The function to apply on each element of the list.
  571. * @return The final result after the left-fold reduction.
  572. */
  573. public A foldLeft1(final F<A, F<A, A>> f) {
  574. if (isEmpty())
  575. throw Bottom.error("Undefined: foldLeft1 on empty list");
  576. return tail().foldLeft(f, head());
  577. }
  578. /**
  579. * Reverse this list in constant stack space.
  580. *
  581. * @return A new list that is the reverse of this one.
  582. */
  583. public List<A> reverse() {
  584. return foldLeft(new F<List<A>, F<A, List<A>>>() {
  585. public F<A, List<A>> f(final List<A> as) {
  586. return new F<A, List<A>>() {
  587. public List<A> f(final A a) {
  588. return cons(a, as);
  589. }
  590. };
  591. }
  592. }, List.<A>nil());
  593. }
  594. /**
  595. * Returns the element at the given index if it exists, fails otherwise.
  596. *
  597. * @param i The index at which to get the element to return.
  598. * @return The element at the given index if it exists, fails otherwise.
  599. */
  600. public A index(final int i) {
  601. if (i < 0 || i > length() - 1)
  602. throw Bottom.error("index " + i + " out of range on list with length " + length());
  603. else {
  604. List<A> xs = this;
  605. for (int c = 0; c < i; c++) {
  606. xs = xs.tail();
  607. }
  608. return xs.head();
  609. }
  610. }
  611. /**
  612. * Takes the given number of elements from the head of this list if they are available.
  613. *
  614. * @param i The maximum number of elements to take from this list.
  615. * @return A new list with a length the same, or less than, this list.
  616. */
  617. public List<A> take(final int i) {
  618. return i <= 0 || isEmpty() ? List.<A>nil() : cons(head(), tail().take(i - 1));
  619. }
  620. /**
  621. * Drops the given number of elements from the head of this list if they are available.
  622. *
  623. * @param i The number of elements to drop from the head of this list.
  624. * @return A list with a length the same, or less than, this list.
  625. */
  626. public List<A> drop(final int i) {
  627. int c = 0;
  628. List<A> xs = this;
  629. //noinspection ForLoopWithMissingComponent,StatementWithEmptyBody
  630. for (; xs.isNotEmpty() && c < i; xs = xs.tail())
  631. c++;
  632. return xs;
  633. }
  634. /**
  635. * Splits this list into two lists at the given index. If the index goes out of bounds, then it is
  636. * normalised so that this function never fails.
  637. *
  638. * @param i The index at which to split this list in two parts.
  639. * @return A pair of lists split at the given index of this list.
  640. */
  641. public P2<List<A>, List<A>> splitAt(final int i) {
  642. P2<List<A>, List<A>> s = P.p(List.<A>nil(), List.<A>nil());
  643. int c = 0;
  644. for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) {
  645. final A h = xs.head();
  646. s = c < i ? s.map1(new F<List<A>, List<A>>() {
  647. public List<A> f(final List<A> as) {
  648. return as.snoc(h);
  649. }
  650. }) : s.map2(new F<List<A>, List<A>>() {
  651. public List<A> f(final List<A> as) {
  652. return as.snoc(h);
  653. }
  654. });
  655. c++;
  656. }
  657. return s;
  658. }
  659. /**
  660. * Splits this list into lists of the given size. If the size of this list is not evenly divisible by
  661. * the given number, the last partition will contain the remainder.
  662. *
  663. * @param n The size of the partitions into which to split this list.
  664. * @return A list of sublists of this list, of at most the given size.
  665. */
  666. public List<List<A>> partition(final int n) {
  667. if (n < 1)
  668. throw Bottom.error("Can't create list partitions shorter than 1 element long.");
  669. if (isEmpty())
  670. throw Bottom.error("Partition on empty list.");
  671. return unfold(new F<List<A>, Option<P2<List<A>, List<A>>>>() {
  672. public Option<P2<List<A>, List<A>>> f(final List<A> as) {
  673. return as.isEmpty() ? Option.<P2<List<A>, List<A>>>none() : Option.some(as.splitAt(n));
  674. }
  675. }, this);
  676. }
  677. /**
  678. * Returns the list of initial segments of this list, shortest first.
  679. *
  680. * @return The list of initial segments of this list, shortest first.
  681. */
  682. public List<List<A>> inits() {
  683. List<List<A>> s = single(List.<A>nil());
  684. if (isNotEmpty())
  685. s = s.append(tail().inits().map(List.<A>cons().f(head())));
  686. return s;
  687. }
  688. /**
  689. * Returns the list of final segments of this list, longest first.
  690. *
  691. * @return The list of final segments of this list, longest first.
  692. */
  693. public List<List<A>> tails() {
  694. if (isEmpty())
  695. return single(List.<A>nil());
  696. else
  697. return cons(this, tail().tails());
  698. }
  699. /**
  700. * Sorts this list using the given order over elements using a <em>merge sort</em> algorithm.
  701. *
  702. * @param o The order over the elements of this list.
  703. * @return A sorted list according to the given order.
  704. */
  705. public List<A> sort(final Ord<A> o) {
  706. if (isEmpty())
  707. return nil();
  708. else if (tail().isEmpty())
  709. return this;
  710. else {
  711. final class Merge<A> {
  712. List<A> merge(final List<A> xs, final List<A> ys, final Ord<A> o) {
  713. return xs.isEmpty() ?
  714. ys :
  715. ys.isEmpty() ?
  716. xs :
  717. o.isGreaterThan(ys.head(), xs.head()) ?
  718. cons(xs.head(), merge(xs.tail(), ys, o)) :
  719. cons(ys.head(), merge(xs, ys.tail(), o));
  720. }
  721. }
  722. final P2<List<A>, List<A>> s = splitAt(length() / 2);
  723. return new Merge<A>().merge(s._1().sort(o), s._2().sort(o), o);
  724. }
  725. }
  726. /**
  727. * Zips this list with the given list using the given function to produce a new list. If this list
  728. * and the given list have different lengths, then the longer list is normalised so this function
  729. * never fails.
  730. *
  731. * @param bs The list to zip this list with.
  732. * @param f The function to zip this list and the given list with.
  733. * @return A new list with a length the same as the shortest of this list and the given list.
  734. */
  735. public <B, C> List<C> zipWith(final List<B> bs, final F<A, F<B, C>> f) {
  736. return isEmpty() || bs.isEmpty() ? List.<C>nil() : cons(f.f(head()).f(bs.head()), tail().zipWith(bs.tail(), f));
  737. }
  738. /**
  739. * Zips this list with the given list using the given function to produce a new list. If this list
  740. * and the given list have different lengths, then the longer list is normalised so this function
  741. * never fails.
  742. *
  743. * @param bs The list to zip this list with.
  744. * @param f The function to zip this list and the given list with.
  745. * @return A new list with a length the same as the shortest of this list and the given list.
  746. */
  747. public <B, C> List<C> zipWith(final List<B> bs, final F2<A, B, C> f) {
  748. return zipWith(bs, Function.curry(f));
  749. }
  750. /**
  751. * Provides a first-class version of zipWith
  752. *
  753. * @return The first-class version of zipWith
  754. */
  755. public static <A, B, C> F<List<A>, F<List<B>, F<F<A, F<B, C>>, List<C>>>> zipWith() {
  756. return Function.curry(new F3<List<A>, List<B>, F<A, F<B, C>>, List<C>>() {
  757. public List<C> f(final List<A> as, final List<B> bs, final F<A, F<B, C>> f) {
  758. return as.zipWith(bs, f);
  759. }
  760. });
  761. }
  762. /**
  763. * Zips this list with the given list to produce a list of pairs. If this list and the given list
  764. * have different lengths, then the longer list is normalised so this function never fails.
  765. *
  766. * @param bs The list to zip this list with.
  767. * @return A new list with a length the same as the shortest of this list and the given list.
  768. */
  769. public <B> List<P2<A, B>> zip(final List<B> bs) {
  770. final F<A, F<B, P2<A, B>>> __2 = P.p2();
  771. return zipWith(bs, __2);
  772. }
  773. /**
  774. * The first-class version of the zip function.
  775. *
  776. * @return A function that zips the given lists to produce a list of pairs.
  777. */
  778. public static <A, B> F<List<A>, F<List<B>, List<P2<A, B>>>> zip() {
  779. return Function.curry(new F2<List<A>, List<B>, List<P2<A, B>>>() {
  780. public List<P2<A, B>> f(final List<A> as, final List<B> bs) {
  781. return as.zip(bs);
  782. }
  783. });
  784. }
  785. /**
  786. * Zips this list with the index of its element as a pair.
  787. *
  788. * @return A new list with the same length as this list.
  789. */
  790. public List<P2<A, Integer>> zipIndex() {
  791. return zipWith(range(0, length()), new F<A, F<Integer, P2<A, Integer>>>() {
  792. public F<Integer, P2<A, Integer>> f(final A a) {
  793. return new F<Integer, P2<A, Integer>>() {
  794. public P2<A, Integer> f(final Integer i) {
  795. return P.p(a, i);
  796. }
  797. };
  798. }
  799. });
  800. }
  801. /**
  802. * Appends (snoc) the given element to this list to produce a new list.
  803. *
  804. * @param a The element to append to this list.
  805. * @return A new list with the given element appended.
  806. */
  807. public List<A> snoc(final A a) {
  808. return Buffer.fromList(this).snoc(a).toList();
  809. }
  810. /**
  811. * Returns <code>true</code> if the predicate holds for all of the elements of this list,
  812. * <code>false</code> otherwise (<code>true</code> for the empty list).
  813. *
  814. * @param f The predicate function to test on each element of this list.
  815. * @return <code>true</code> if the predicate holds for all of the elements of this list,
  816. * <code>false</code> otherwise.
  817. */
  818. public boolean forall(final F<A, Boolean> f) {
  819. return isEmpty() || f.f(head()) && tail().forall(f);
  820. }
  821. /**
  822. * Returns <code>true</code> if the predicate holds for at least one of the elements of this list,
  823. * <code>false</code> otherwise (<code>false</code> for the empty list).
  824. *
  825. * @param f The predicate function to test on the elements of this list.
  826. * @return <code>true</code> if the predicate holds for at least one of the elements of this
  827. * list.
  828. */
  829. public boolean exists(final F<A, Boolean> f) {
  830. return find(f).isSome();
  831. }
  832. /**
  833. * Finds the first occurrence of an element that matches the given predicate or no value if no
  834. * elements match.
  835. *
  836. * @param f The predicate function to test on elements of this list.
  837. * @return The first occurrence of an element that matches the given predicate or no value if no
  838. * elements match.
  839. */
  840. public Option<A> find(final F<A, Boolean> f) {
  841. for (List<A> as = this; as.isNotEmpty(); as = as.tail()) {
  842. if (f.f(as.head()))
  843. return Option.some(as.head());
  844. }
  845. return Option.none();
  846. }
  847. /**
  848. * Intersperses the given argument between each element of this list.
  849. *
  850. * @param a The separator to intersperse in this list.
  851. * @return A list with the given separator interspersed.
  852. */
  853. public List<A> intersperse(final A a) {
  854. return isEmpty() || tail().isEmpty() ?
  855. this :
  856. cons(head(), cons(a, tail().intersperse(a)));
  857. }
  858. /**
  859. * Intersperses this list through the given list then joins the results.
  860. *
  861. * @param as The list to intersperse through.
  862. * @return This list through the given list then joins the results.
  863. */
  864. @SuppressWarnings({"unchecked"})
  865. public List<A> intercalate(final List<List<A>> as) {
  866. return join(as.intersperse(this));
  867. }
  868. /**
  869. * Removes duplicates according to object equality.
  870. *
  871. * @return A list without duplicates according to object equality.
  872. */
  873. public List<A> nub() {
  874. return nub(Equal.<A>anyEqual());
  875. }
  876. /**
  877. * Removes duplicates according to the given equality. Warning: O(n^2).
  878. *
  879. * @param eq Equality over the elements.
  880. * @return A list without duplicates.
  881. */
  882. public List<A> nub(final Equal<A> eq) {
  883. return isEmpty() ? this : cons(head(), tail().filter(new F<A, Boolean>() {
  884. public Boolean f(final A a) {
  885. return !eq.eq(a, head());
  886. }
  887. }).nub(eq));
  888. }
  889. /**
  890. * Removes duplicates according to the given ordering. This function is O(n).
  891. *
  892. * @param o An ordering for the elements.
  893. * @return A list without duplicates.
  894. */
  895. public List<A> nub(final Ord<A> o) {
  896. return sort(o).group(o.equal()).map(List.<A>head_());
  897. }
  898. /**
  899. * First-class head function.
  900. *
  901. * @return A function that gets the head of a given list.
  902. */
  903. public static <A> F<List<A>, A> head_() {
  904. return new F<List<A>, A>() {
  905. public A f(final List<A> list) {
  906. return list.head();
  907. }
  908. };
  909. }
  910. /**
  911. * First-class tail function.
  912. *
  913. * @return A function that gets the tail of a given list.
  914. */
  915. public static <A> F<List<A>, List<A>> tail_() {
  916. return new F<List<A>, List<A>>() {
  917. public List<A> f(final List<A> list) {
  918. return list.tail();
  919. }
  920. };
  921. }
  922. /**
  923. * Returns a new list of all the items in this list that do not appear in the given list.
  924. *
  925. * @param eq an equality for the items of the lists.
  926. * @param xs a list to subtract from this list.
  927. * @return a list of all the items in this list that do not appear in the given list.
  928. */
  929. public List<A> minus(final Equal<A> eq, final List<A> xs) {
  930. return removeAll(Function.compose(Monoid.disjunctionMonoid.sumLeft(), xs.mapM(Function.curry(eq.eq()))));
  931. }
  932. /**
  933. * Maps the given function of arity-2 across this list and returns a function that applies all the resulting
  934. * functions to a given argument.
  935. *
  936. * @param f A function of arity-2
  937. * @return A function that, when given an argument, applies the given function to that argument and every element
  938. * in this list.
  939. */
  940. public <B, C> F<B, List<C>> mapM(final F<A, F<B, C>> f) {
  941. return List.sequence(map(f));
  942. }
  943. /**
  944. * Returns the index of the first element in this list which is equal (by the given equality) to the
  945. * query element, or None if there is no such element.
  946. *
  947. * @param e An equality for this list's elements.
  948. * @param a A query element.
  949. * @return The index of the first element in this list which is equal (by the given equality) to the
  950. * query element, or None if there is no such element.
  951. */
  952. public Option<Integer> elementIndex(final Equal<A> e, final A a) {
  953. return lookup(e, zipIndex(), a);
  954. }
  955. /**
  956. * Returns the last element of this list. Undefined for the empty list.
  957. *
  958. * @return The last element of this list or throws an error if this list is empty.
  959. */
  960. public A last() {
  961. A a = head();
  962. for (List<A> xs = tail(); xs.isNotEmpty(); xs = xs.tail())
  963. a = xs.head();
  964. return a;
  965. }
  966. /**
  967. * Inserts the given element before the first element that is greater than or equal to it according
  968. * to the given ordering.
  969. *
  970. * @param f An ordering function to compare elements.
  971. * @param x The element to insert.
  972. * @return A new list with the given element inserted before the first element that is greater than or equal to
  973. * it according to the given ordering.
  974. */
  975. public List<A> insertBy(final F<A, F<A, Ordering>> f, final A x) {
  976. List<A> ys = this;
  977. Buffer<A> xs = Buffer.empty();
  978. while (ys.isNotEmpty() && f.f(x).f(ys.head()) == Ordering.GT) {
  979. xs = xs.snoc(ys.head());
  980. ys = ys.tail();
  981. }
  982. return xs.append(ys.cons(x)).toList();
  983. }
  984. /**
  985. * Returns the most common element in this list.
  986. *
  987. * @param o An ordering for the elements of the list.
  988. * @return The most common element in this list.
  989. */
  990. public A mode(final Ord<A> o) {
  991. return sort(o).group(o.equal()).maximum(Ord.intOrd.comap(List.<A>length_())).head();
  992. }
  993. /**
  994. * First-class length.
  995. *
  996. * @return A function that gets the length of a given list.
  997. */
  998. public static <A> F<List<A>, Integer> length_() {
  999. return new F<List<A>, Integer>() {
  1000. public Integer f(final List<A> a) {
  1001. return a.length();
  1002. }
  1003. };
  1004. }
  1005. /**
  1006. * Returns the maximum element in this list according to the given ordering.
  1007. *
  1008. * @param o An ordering for the elements of the list.
  1009. * @return The maximum element in this list according to the given ordering.
  1010. */
  1011. public A maximum(final Ord<A> o) {
  1012. return foldLeft1(o.max);
  1013. }
  1014. /**
  1015. * Returns the minimum element in this list according to the given ordering.
  1016. *
  1017. * @param o An ordering for the elements of the list.
  1018. * @return The minimum element in this list according to the given ordering.
  1019. */
  1020. public A minimum(final Ord<A> o) {
  1021. return foldLeft1(o.min);
  1022. }
  1023. /**
  1024. * Projects an immutable collection of this list.
  1025. *
  1026. * @return An immutable collection of this list.
  1027. */
  1028. public Collection<A> toCollection() {
  1029. return new AbstractCollection<A>() {
  1030. public Iterator<A> iterator() {
  1031. return new Iterator<A>() {
  1032. private List<A> xs = List.this;
  1033. public boolean hasNext() {
  1034. return xs.isNotEmpty();
  1035. }
  1036. public A next() {
  1037. if (xs.isEmpty())
  1038. throw new NoSuchElementException();
  1039. else {
  1040. final A a = xs.head();
  1041. xs = xs.tail();
  1042. return a;
  1043. }
  1044. }
  1045. public void remove() {
  1046. throw new UnsupportedOperationException();
  1047. }
  1048. };
  1049. }
  1050. public int size() {
  1051. return length();
  1052. }
  1053. };
  1054. }
  1055. private static final class Nil<A> extends List<A> {
  1056. public A head() {
  1057. throw Bottom.error("head on empty list");
  1058. }
  1059. public List<A> tail() {
  1060. throw Bottom.error("tail on empty list");
  1061. }
  1062. }
  1063. private static final class Cons<A> extends List<A> {
  1064. private final A head;
  1065. private List<A> tail;
  1066. Cons(final A head, final List<A> tail) {
  1067. this.head = head;
  1068. this.tail = tail;
  1069. }
  1070. public A head() {
  1071. return head;
  1072. }
  1073. public List<A> tail() {
  1074. return tail;
  1075. }
  1076. private void tail(final List<A> tail) {
  1077. this.tail = tail;
  1078. }
  1079. }
  1080. /**
  1081. * Constructs a list from the given elements.
  1082. *
  1083. * @param as The elements to construct a list with.
  1084. * @return A list with the given elements.
  1085. */
  1086. public static <A> List<A> list(final A... as) {
  1087. return Array.array(as).toList();
  1088. }
  1089. /**
  1090. * Returns an empty list.
  1091. *
  1092. * @return An empty list.
  1093. */
  1094. public static <A> List<A> nil() {
  1095. return new Nil<A>();
  1096. }
  1097. /**
  1098. * Returns a function that prepends (cons) an element to a list to produce a new list.
  1099. *
  1100. * @return A function that prepends (cons) an element to a list to produce a new list.
  1101. */
  1102. public static <A> F<A, F<List<A>, List<A>>> cons() {
  1103. return new F<A, F<List<A>, List<A>>>() {
  1104. public F<List<A>, List<A>> f(final A a) {
  1105. return new F<List<A>, List<A>>() {
  1106. public List<A> f(final List<A> tail) {
  1107. return cons(a, tail);
  1108. }
  1109. };
  1110. }
  1111. };
  1112. }
  1113. /**
  1114. * Returns a function that prepends a value to the given list.
  1115. *
  1116. * @param tail The list to prepend to.
  1117. * @return A function that prepends a value to the given list.
  1118. */
  1119. public static <A> F<A, List<A>> cons(final List<A> tail) {
  1120. return new F<A, List<A>>() {
  1121. public List<A> f(final A a) {
  1122. return tail.cons(a);
  1123. }
  1124. };
  1125. }
  1126. /**
  1127. * Returns a function that prepends the given value to a list.
  1128. *
  1129. * @param a The value to prepend to a list.
  1130. * @return A function that prepends the given value to a list.
  1131. */
  1132. public static <A> F<List<A>, List<A>> cons_(final A a) {
  1133. return new F<List<A>, List<A>>() {
  1134. public List<A> f(final List<A> as) {
  1135. return as.cons(a);
  1136. }
  1137. };
  1138. }
  1139. /**
  1140. * Prepends the given head element to the given tail element to produce a new list.
  1141. *
  1142. * @param head The element to prepend.
  1143. * @param tail The list to prepend to.
  1144. * @return The list with the given element prepended.
  1145. */
  1146. public static <A> List<A> cons(final A head, final List<A> tail) {
  1147. return new Cons<A>(head, tail);
  1148. }
  1149. /**
  1150. * Returns a function that determines whether a given list is empty.
  1151. *
  1152. * @return A function that determines whether a given list is empty.
  1153. */
  1154. public static <A> F<List<A>, Boolean> isEmpty_() {
  1155. return new F<List<A>, Boolean>() {
  1156. public Boolean f(final List<A> as) {
  1157. return as.isEmpty();
  1158. }
  1159. };
  1160. }
  1161. /**
  1162. * Returns a function that determines whether a given list is not empty.
  1163. *
  1164. * @return A function that determines whether a given list is not empty.
  1165. */
  1166. public static <A> F<List<A>, Boolean> isNotEmpty_() {
  1167. return new F<List<A>, Boolean>() {
  1168. public Boolean f(final List<A> as) {
  1169. return as.isNotEmpty();
  1170. }
  1171. };
  1172. }
  1173. /**
  1174. * Joins the given list of lists using a bind operation.
  1175. *
  1176. * @param o The list of lists to join.
  1177. * @return A new list that is the join of the given lists.
  1178. */
  1179. public static <A> List<A> join(final List<List<A>> o) {
  1180. final F<List<A>, List<A>> id = Function.identity();
  1181. return o.bind(id);
  1182. }
  1183. /**
  1184. * A first-class version of join
  1185. *
  1186. * @return A function that joins a list of lists using a bind operation.
  1187. */
  1188. public static <A> F<List<List<A>>, List<A>> join() {
  1189. return new F<List<List<A>>, List<A>>() {
  1190. public List<A> f(final List<List<A>> as) {
  1191. return join(as);
  1192. }
  1193. };
  1194. }
  1195. /**
  1196. * Unfolds across the given function starting at the given value to produce a list.
  1197. *
  1198. * @param f The function to unfold across.
  1199. * @param b The start value to begin the unfold.
  1200. * @return A new list that is a result of unfolding until the function does not produce a value.
  1201. */
  1202. public static <A, B> List<A> unfold(final F<B, Option<P2<A, B>>> f, final B b) {
  1203. Buffer<A> buf = Buffer.empty();
  1204. for (Option<P2<A, B>> o = f.f(b); o.isSome(); o = f.f(o.some()._2())) {
  1205. buf = buf.snoc(o.some()._1());
  1206. }
  1207. return buf.toList();
  1208. }
  1209. /**
  1210. * Transforms a list of pairs into a list of first components and a list of second components.
  1211. *
  1212. * @param xs The list of pairs to transform.sp
  1213. * @return A list of first components and a list of second components.
  1214. */
  1215. public static <A, B> P2<List<A>, List<B>> unzip(final List<P2<A, B>> xs) {
  1216. Buffer<A> ba = Buffer.empty();
  1217. Buffer<B> bb = Buffer.empty();
  1218. for (final P2<A, B> p : xs) {
  1219. ba = ba.snoc(p._1());
  1220. bb = bb.snoc(p._2());
  1221. }
  1222. return P.p(ba.toList(), bb.toList());
  1223. }
  1224. /**
  1225. * Returns a list of the given value replicated the given number of times.
  1226. *
  1227. * @param n The number of times to replicate the given value.
  1228. * @param a The value to replicate.
  1229. * @return A list of the given value replicated the given number of times.
  1230. */
  1231. public static <A> List<A> replicate(final int n, final A a) {
  1232. return n <= 0 ? List.<A>nil() : replicate(n - 1, a).cons(a);
  1233. }
  1234. /**
  1235. * Returns a list of integers from the given <code>from</code> value (inclusive) to the given
  1236. * <code>to</code> value (exclusive).
  1237. *
  1238. * @param from The minimum value for the list (inclusive).
  1239. * @param to The maximum value for the list (exclusive).
  1240. * @return A list of integers from the given <code>from</code> value (inclusive) to the given
  1241. * <code>to</code> value (exclusive).
  1242. */
  1243. public static List<Integer> range(final int from, final int to) {
  1244. return from >= to ? List.<Integer>nil() : cons(from, range(from + 1, to));
  1245. }
  1246. /**
  1247. * Returns a list of characters from the given string. The inverse of this function is {@link
  1248. * #asString(List)}.
  1249. *
  1250. * @param s The string to produce the list of characters from.
  1251. * @return A list of characters from the given string.
  1252. */
  1253. public static List<Character> fromString(final String s) {
  1254. List<Character> cs = nil();
  1255. for (int i = s.length() - 1; i >= 0; i--)
  1256. cs = cons(s.charAt(i), cs);
  1257. return cs;
  1258. }
  1259. /**
  1260. * A first-class <code>fromString</code>.
  1261. *
  1262. * @return A first-class <code>fromString</code>.
  1263. */
  1264. public static F<String, List<Character>> fromString() {
  1265. return new F<String, List<Character>>() {
  1266. public List<Character> f(final String s) {
  1267. return fromString(s);
  1268. }
  1269. };
  1270. }
  1271. /**
  1272. * Returns a string from the given list of characters. The invers of this function is {@link
  1273. * #fromString(String)}.
  1274. *
  1275. * @param cs The list of characters to produce the string from.
  1276. * @return A string from the given list of characters.
  1277. */
  1278. public static String asString(final List<Character> cs) {
  1279. final StringBuilder sb = new StringBuilder();
  1280. cs.foreach(new F<Character, Unit>() {
  1281. public Unit f(final Character c) {
  1282. sb.append(c);
  1283. return Unit.unit();
  1284. }
  1285. });
  1286. return sb.toString();
  1287. }
  1288. /**
  1289. * A first-class <code>asString</code>.
  1290. *
  1291. * @return A first-class <code>asString</code>.
  1292. */
  1293. public static F<List<Character>, String> asString() {
  1294. return new F<List<Character>, String>() {
  1295. public String f(final List<Character> cs) {
  1296. return asString(cs);
  1297. }
  1298. };
  1299. }
  1300. /**
  1301. * Returns a list of one element containing the given value.
  1302. *
  1303. * @param a The value for the head of the returned list.
  1304. * @return A list of one element containing the given value.
  1305. */
  1306. public static <A> List<A> single(final A a) {
  1307. return cons(a, List.<A>nil());
  1308. }
  1309. /**
  1310. * Creates a list where the first item is calculated by applying the function on the third argument,
  1311. * the second item by applying the function on the previous result and so on.
  1312. *
  1313. * @param f The function to iterate with.
  1314. * @param p The predicate which must be true for the next item in order to continue the iteration.
  1315. * @param a The input to the first iteration.
  1316. * @return A list where the first item is calculated by applying the function on the third argument,
  1317. * the second item by applying the function on the previous result and so on.
  1318. */
  1319. public static <A> List<A> iterateWhile(final F<A, A> f, final F<A, Boolean> p, final A a) {
  1320. return unfold(
  1321. new F<A, Option<P2<A, A>>>() {
  1322. public Option<P2<A, A>> f(final A o) {
  1323. return Option.iif(new F<P2<A, A>, Boolean>() {
  1324. public Boolean f(final P2<A, A> p2) {
  1325. return p.f(o);
  1326. }
  1327. }, P.p(o, f.f(o)));
  1328. }
  1329. }
  1330. , a);
  1331. }
  1332. /**
  1333. * Returns an associated value with the given key in the list of pairs.
  1334. *
  1335. * @param e The test for equality on keys.
  1336. * @param x The list of pairs to search.
  1337. * @param a The key value to find the associated value of.
  1338. * @return An associated value with the given key in the list of pairs.
  1339. */
  1340. public static <A, B> Option<B> lookup(final Equal<A> e, final List<P2<A, B>> x, final A a) {
  1341. return x.find(new F<P2<A, B>, Boolean>() {
  1342. public Boolean f(final P2<A, B> p) {
  1343. return e.eq(p._1(), a);
  1344. }
  1345. }).map(P2.<A, B>__2());
  1346. }
  1347. /**
  1348. * Returns a partially applied version of {@link #lookup(Equal, List, Object)}.
  1349. *
  1350. * @param e The test for equality on keys.
  1351. * @return A partially applied version of {@link #lookup(Equal, List, Object)}.
  1352. */
  1353. public static <A, B> F2<List<P2<A, B>>, A, Option<B>> lookup(final Equal<A> e) {
  1354. return new F2<List<P2<A, B>>, A, Option<B>>() {
  1355. public Option<B> f(final List<P2<A, B>> x, final A a) {
  1356. return lookup(e, x, a);
  1357. }
  1358. };
  1359. }
  1360. /**
  1361. * Provides a first-class version of bind()
  1362. *
  1363. * @return The bind function for lists.
  1364. */
  1365. public static <A, B> F<F<A, List<B>>, F<List<A>, List<B>>> bind_() {
  1366. return Function.curry(new F2<F<A, List<B>>, List<A>, List<B>>() {
  1367. public List<B> f(final F<A, List<B>> f, final List<A> as) {
  1368. return as.bind(f);
  1369. }
  1370. });
  1371. }
  1372. /**
  1373. * Provides a first-class version of map()
  1374. *
  1375. * @return The map function for lists.
  1376. */
  1377. public static <A, B> F<F<A, B>, F<List<A>, List<B>>> map_() {
  1378. return Function.curry(new F2<F<A, B>, List<A>, List<B>>() {
  1379. public List<B> f(final F<A, B> f, final List<A> as) {
  1380. return as.map(f);
  1381. }
  1382. });
  1383. }
  1384. /**
  1385. * Turn a list of functions into a function returning a list.
  1386. *
  1387. * @param fs The list of functions to sequence into a single function that returns a list.
  1388. * @return A function that, when given an argument, applies all the functions in the given list to it
  1389. * and returns a list of the results.
  1390. */
  1391. public static <A, B> F<B, List<A>> sequence(final List<F<B, A>> fs) {
  1392. return fs.foldRight(Function.<A, List<A>, List<A>, B>lift(List.<A>cons()), Function
  1393. .<B, List<A>>constant(List.<A>nil()));
  1394. }
  1395. /**
  1396. * Provides a first-class version of foldLeft.
  1397. *
  1398. * @return The left fold function for lists.
  1399. */
  1400. public static <A, B> F<F<B, F<A, B>>, F<B, F<List<A>, B>>> foldLeft() {
  1401. return Function.curry(new F3<F<B, F<A, B>>, B, List<A>, B>() {
  1402. public B f(final F<B, F<A, B>> f, final B b, final List<A> as) {
  1403. return as.foldLeft(f, b);
  1404. }
  1405. });
  1406. }
  1407. /**
  1408. * Provides a first-class version of take.
  1409. *
  1410. * @return First-class version of take.
  1411. */
  1412. public static <A> F<Integer, F<List<A>, List<A>>> take() {
  1413. return Function.curry(new F2<I

Large files files are truncated, but you can click here to view the full file