Mercurial > hg > Members > tatsuki > functionaljava-master > core
comparison src/main/java/fj/data/List.java @ 0:fe80c1edf1be
add getLoop
author | tatsuki |
---|---|
date | Fri, 20 Mar 2015 21:04:03 +0900 |
parents | |
children | 8ed7d71e8617 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:fe80c1edf1be |
---|---|
1 package fj.data; | |
2 | |
3 import static fj.Bottom.error; | |
4 import fj.F2Functions; | |
5 import fj.Equal; | |
6 import fj.F; | |
7 import fj.F2; | |
8 import fj.F3; | |
9 import fj.Function; | |
10 import fj.Hash; | |
11 import fj.Monoid; | |
12 import fj.Ord; | |
13 import fj.P; | |
14 import fj.P1; | |
15 import fj.P2; | |
16 import fj.Show; | |
17 import fj.Unit; | |
18 import static fj.Function.curry; | |
19 import static fj.Function.constant; | |
20 import static fj.Function.identity; | |
21 import static fj.Function.compose; | |
22 import static fj.P.p; | |
23 import static fj.P.p2; | |
24 import static fj.Unit.unit; | |
25 import static fj.data.Array.mkArray; | |
26 import static fj.data.List.Buffer.*; | |
27 import static fj.data.Option.none; | |
28 import static fj.data.Option.some; | |
29 import static fj.function.Booleans.not; | |
30 import static fj.Ordering.GT; | |
31 import static fj.Ord.intOrd; | |
32 | |
33 import fj.Ordering; | |
34 import fj.control.Trampoline; | |
35 import fj.function.Effect1; | |
36 | |
37 import java.util.AbstractCollection; | |
38 import java.util.Collection; | |
39 import java.util.Iterator; | |
40 import java.util.NoSuchElementException; | |
41 | |
42 /** | |
43 * Provides an in-memory, immutable, singly linked list. | |
44 * | |
45 * @version %build.number% | |
46 */ | |
47 public abstract class List<A> implements Iterable<A> { | |
48 private List() { | |
49 | |
50 } | |
51 | |
52 /** | |
53 * Returns an iterator for this list. This method exists to permit the use in a <code>for</code>-each loop. | |
54 * | |
55 * @return A iterator for this list. | |
56 */ | |
57 public final Iterator<A> iterator() { | |
58 return toCollection().iterator(); | |
59 } | |
60 | |
61 /** | |
62 * The first element of the linked list or fails for the empty list. | |
63 * | |
64 * @return The first element of the linked list or fails for the empty list. | |
65 */ | |
66 public abstract A head(); | |
67 | |
68 /** | |
69 * The list without the first element or fails for the empty list. | |
70 * | |
71 * @return The list without the first element or fails for the empty list. | |
72 */ | |
73 public abstract List<A> tail(); | |
74 | |
75 /** | |
76 * The length of this list. | |
77 * | |
78 * @return The length of this list. | |
79 */ | |
80 public final int length() { | |
81 return foldLeft(new F<Integer, F<A, Integer>>() { | |
82 public F<A, Integer> f(final Integer i) { | |
83 return new F<A, Integer>() { | |
84 public Integer f(final A a) { | |
85 return i + 1; | |
86 } | |
87 }; | |
88 } | |
89 }, 0); | |
90 } | |
91 | |
92 /** | |
93 * Returns <code>true</code> if this list is empty, <code>false</code> otherwise. | |
94 * | |
95 * @return <code>true</code> if this list is empty, <code>false</code> otherwise. | |
96 */ | |
97 public final boolean isEmpty() { | |
98 return this instanceof Nil; | |
99 } | |
100 | |
101 /** | |
102 * Returns <code>false</code> if this list is empty, <code>true</code> otherwise. | |
103 * | |
104 * @return <code>false</code> if this list is empty, <code>true</code> otherwise. | |
105 */ | |
106 public final boolean isNotEmpty() { | |
107 return this instanceof Cons; | |
108 } | |
109 | |
110 /** | |
111 * Performs a reduction on this list using the given arguments. | |
112 * | |
113 * @param nil The value to return if this list is empty. | |
114 * @param cons The function to apply to the head and tail of this list if it is not empty. | |
115 * @return A reduction on this list. | |
116 */ | |
117 public final <B> B list(final B nil, final F<A, F<List<A>, B>> cons) { | |
118 return isEmpty() ? nil : cons.f(head()).f(tail()); | |
119 } | |
120 | |
121 /** | |
122 * Returns the head of this list if there is one or the given argument if this list is empty. | |
123 * | |
124 * @param a The argument to return if this list is empty. | |
125 * @return The head of this list if there is one or the given argument if this list is empty. | |
126 */ | |
127 public final A orHead(final P1<A> a) { | |
128 return isEmpty() ? a._1() : head(); | |
129 } | |
130 | |
131 /** | |
132 * Returns the tail of this list if there is one or the given argument if this list is empty. | |
133 * | |
134 * @param as The argument to return if this list is empty. | |
135 * @return The tail of this list if there is one or the given argument if this list is empty. | |
136 */ | |
137 public final List<A> orTail(final P1<List<A>> as) { | |
138 return isEmpty() ? as._1() : tail(); | |
139 } | |
140 | |
141 /** | |
142 * Returns an option projection of this list; <code>None</code> if empty, or the first element in | |
143 * <code>Some</code>. | |
144 * | |
145 * @return An option projection of this list. | |
146 */ | |
147 public final Option<A> toOption() { | |
148 return isEmpty() ? Option.<A>none() : some(head()); | |
149 } | |
150 | |
151 /** | |
152 * Returns an either projection of this list; the given argument in <code>Left</code> if empty, or | |
153 * the first element in <code>Right</code>. | |
154 * | |
155 * @param x The value to return in left if this list is empty. | |
156 * @return An either projection of this list. | |
157 */ | |
158 public final <X> Either<X, A> toEither(final P1<X> x) { | |
159 return isEmpty() ? Either.<X, A>left(x._1()) : Either.<X, A>right(head()); | |
160 } | |
161 | |
162 /** | |
163 * Returns a stream projection of this list. | |
164 * | |
165 * @return A stream projection of this list. | |
166 */ | |
167 public final Stream<A> toStream() { | |
168 final Stream<A> nil = Stream.nil(); | |
169 return foldRight(new F<A, F<Stream<A>, Stream<A>>>() { | |
170 public F<Stream<A>, Stream<A>> f(final A a) { | |
171 return new F<Stream<A>, Stream<A>>() { | |
172 public Stream<A> f(final Stream<A> as) { | |
173 return as.cons(a); | |
174 } | |
175 }; | |
176 } | |
177 }, nil); | |
178 } | |
179 | |
180 /** | |
181 * Returns a array projection of this list. | |
182 * | |
183 * @return A array projection of this list. | |
184 */ | |
185 @SuppressWarnings({"unchecked"}) | |
186 public final Array<A> toArray() { | |
187 final Object[] a = new Object[length()]; | |
188 List<A> x = this; | |
189 for (int i = 0; i < length(); i++) { | |
190 a[i] = x.head(); | |
191 x = x.tail(); | |
192 } | |
193 | |
194 return mkArray(a); | |
195 } | |
196 | |
197 /** | |
198 * Returns a array projection of this list. | |
199 * | |
200 * @param c The class type of the array to return. | |
201 * @return A array projection of this list. | |
202 */ | |
203 @SuppressWarnings({"unchecked", "UnnecessaryFullyQualifiedName"}) | |
204 public final Array<A> toArray(final Class<A[]> c) { | |
205 final A[] a = (A[]) java.lang.reflect.Array.newInstance(c.getComponentType(), length()); | |
206 List<A> x = this; | |
207 for (int i = 0; i < length(); i++) { | |
208 a[i] = x.head(); | |
209 x = x.tail(); | |
210 } | |
211 | |
212 return Array.array(a); | |
213 } | |
214 | |
215 /** | |
216 * Returns an array from this list. | |
217 * | |
218 * @param c The class type of the array to return. | |
219 * @return An array from this list. | |
220 */ | |
221 public final A[] array(final Class<A[]> c) { | |
222 return toArray(c).array(c); | |
223 } | |
224 | |
225 /** | |
226 * Prepends (cons) the given element to this list to product a new list. | |
227 * | |
228 * @param a The element to prepend. | |
229 * @return A new list with the given element at the head. | |
230 */ | |
231 public final List<A> cons(final A a) { | |
232 return new Cons<A>(a, this); | |
233 } | |
234 | |
235 /** | |
236 * Prepends (cons) the given element to this list to product a new list. This method is added to prevent conflict with | |
237 * overloads. | |
238 * | |
239 * @param a The element to prepend. | |
240 * @return A new list with the given element at the head. | |
241 */ | |
242 public final List<A> conss(final A a) { | |
243 return new Cons<A>(a, this); | |
244 } | |
245 | |
246 /** | |
247 * Maps the given function across this list. | |
248 * | |
249 * @param f The function to map across this list. | |
250 * @return A new list after the given function has been applied to each element. | |
251 */ | |
252 public final <B> List<B> map(final F<A, B> f) { | |
253 final Buffer<B> bs = empty(); | |
254 | |
255 for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) { | |
256 bs.snoc(f.f(xs.head())); | |
257 } | |
258 | |
259 return bs.toList(); | |
260 } | |
261 | |
262 /** | |
263 * Performs a side-effect for each element of this list. | |
264 * | |
265 * @param f The side-effect to perform for the given element. | |
266 * @return The unit value. | |
267 */ | |
268 public final Unit foreach(final F<A, Unit> f) { | |
269 for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) { | |
270 f.f(xs.head()); | |
271 } | |
272 | |
273 return unit(); | |
274 } | |
275 | |
276 /** | |
277 * Performs a side-effect for each element of this list. | |
278 * | |
279 * @param f The side-effect to perform for the given element. | |
280 */ | |
281 public final void foreachDoEffect(final Effect1<A> f) { | |
282 for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) { | |
283 f.f(xs.head()); | |
284 } | |
285 } | |
286 | |
287 /** | |
288 * Filters elements from this list by returning only elements which produce <code>true</code> when | |
289 * the given function is applied to them. | |
290 * | |
291 * @param f The predicate function to filter on. | |
292 * @return A new list whose elements all match the given predicate. | |
293 */ | |
294 public final List<A> filter(final F<A, Boolean> f) { | |
295 final Buffer<A> b = empty(); | |
296 | |
297 for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) { | |
298 final A h = xs.head(); | |
299 if (f.f(h)) { | |
300 b.snoc(h); | |
301 } | |
302 } | |
303 | |
304 return b.toList(); | |
305 } | |
306 | |
307 /** | |
308 * Filters elements from this list by returning only elements which produce <code>false</code> when | |
309 * the given function is applied to them. | |
310 * | |
311 * @param f The predicate function to filter on. | |
312 * @return A new list whose elements do not match the given predicate. | |
313 */ | |
314 public final List<A> removeAll(final F<A, Boolean> f) { | |
315 return filter(compose(not, f)); | |
316 } | |
317 | |
318 /** | |
319 * Removes the first element that equals the given object. | |
320 * To remove all matches, use <code>removeAll(e.eq(a))</code> | |
321 * | |
322 * @param a The element to remove | |
323 * @param e An <code>Equals</code> instance for the element's type. | |
324 * @return A new list whose elements do not match the given predicate. | |
325 */ | |
326 public final List<A> delete(final A a, final Equal<A> e) { | |
327 final P2<List<A>, List<A>> p = span(compose(not, e.eq(a))); | |
328 return p._2().isEmpty() ? p._1() : p._1().append(p._2().tail()); | |
329 } | |
330 | |
331 /** | |
332 * Returns the first elements of the head of this list that match the given predicate function. | |
333 * | |
334 * @param f The predicate function to apply on this list until it finds an element that does not | |
335 * hold, or the list is exhausted. | |
336 * @return The first elements of the head of this list that match the given predicate function. | |
337 */ | |
338 public final List<A> takeWhile(final F<A, Boolean> f) { | |
339 final Buffer<A> b = empty(); | |
340 boolean taking = true; | |
341 | |
342 for (List<A> xs = this; xs.isNotEmpty() && taking; xs = xs.tail()) { | |
343 final A h = xs.head(); | |
344 if (f.f(h)) { | |
345 b.snoc(h); | |
346 } else { | |
347 taking = false; | |
348 } | |
349 } | |
350 | |
351 return b.toList(); | |
352 } | |
353 | |
354 /** | |
355 * Removes elements from the head of this list that do not match the given predicate function | |
356 * until an element is found that does match or the list is exhausted. | |
357 * | |
358 * @param f The predicate function to apply through this list. | |
359 * @return The list whose first element does not match the given predicate function. | |
360 */ | |
361 public final List<A> dropWhile(final F<A, Boolean> f) { | |
362 List<A> xs; | |
363 | |
364 //noinspection StatementWithEmptyBody | |
365 for (xs = this; xs.isNotEmpty() && f.f(xs.head()); xs = xs.tail()) ; | |
366 | |
367 return xs; | |
368 } | |
369 | |
370 /** | |
371 * Returns a tuple where the first element is the longest prefix of this list that satisfies | |
372 * the given predicate and the second element is the remainder of the list. | |
373 * | |
374 * @param p A predicate to be satisfied by a prefix of this list. | |
375 * @return A tuple where the first element is the longest prefix of this list that satisfies | |
376 * the given predicate and the second element is the remainder of the list. | |
377 */ | |
378 public final P2<List<A>, List<A>> span(final F<A, Boolean> p) { | |
379 final Buffer<A> b = empty(); | |
380 for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) { | |
381 if (p.f(xs.head())) | |
382 b.snoc(xs.head()); | |
383 else | |
384 return P.p(b.toList(), xs); | |
385 } | |
386 return P.p(b.toList(), List.<A>nil()); | |
387 } | |
388 | |
389 /** | |
390 * Returns a tuple where the first element is the longest prefix of this list that does not satisfy | |
391 * the given predicate and the second element is the remainder of the list. | |
392 * | |
393 * @param p A predicate for an element to not satisfy by a prefix of this list. | |
394 * @return A tuple where the first element is the longest prefix of this list that does not satisfy | |
395 * the given predicate and the second element is the remainder of the list. | |
396 */ | |
397 public final P2<List<A>, List<A>> breakk(final F<A, Boolean> p) { | |
398 return span(new F<A, Boolean>() { | |
399 public Boolean f(final A a) { | |
400 return !p.f(a); | |
401 } | |
402 }); | |
403 } | |
404 | |
405 /** | |
406 * Groups elements according to the given equality implementation by longest | |
407 * sequence of equal elements. | |
408 * | |
409 * @param e The equality implementation for the elements. | |
410 * @return A list of grouped elements. | |
411 */ | |
412 public final List<List<A>> group(final Equal<A> e) { | |
413 if (isEmpty()) | |
414 return nil(); | |
415 else { | |
416 final P2<List<A>, List<A>> z = tail().span(e.eq(head())); | |
417 return cons(z._1().cons(head()), z._2().group(e)); | |
418 } | |
419 } | |
420 | |
421 | |
422 /** | |
423 * Binds the given function across each element of this list with a final join. | |
424 * | |
425 * @param f The function to apply to each element of this list. | |
426 * @return A new list after performing the map, then final join. | |
427 */ | |
428 public final <B> List<B> bind(final F<A, List<B>> f) { | |
429 final Buffer<B> b = empty(); | |
430 | |
431 for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) { | |
432 b.append(f.f(xs.head())); | |
433 } | |
434 | |
435 return b.toList(); | |
436 } | |
437 | |
438 /** | |
439 * Binds the given function across each element of this list and the given list with a final | |
440 * join. | |
441 * | |
442 * @param lb A given list to bind the given function with. | |
443 * @param f The function to apply to each element of this list and the given list. | |
444 * @return A new list after performing the map, then final join. | |
445 */ | |
446 public final <B, C> List<C> bind(final List<B> lb, final F<A, F<B, C>> f) { | |
447 return lb.apply(map(f)); | |
448 } | |
449 | |
450 /** | |
451 * Binds the given function across each element of this list and the given list with a final | |
452 * join. | |
453 * | |
454 * @param lb A given list to bind the given function with. | |
455 * @param f The function to apply to each element of this list and the given list. | |
456 * @return A new list after performing the map, then final join. | |
457 */ | |
458 public final <B, C> List<C> bind(final List<B> lb, final F2<A, B, C> f) { | |
459 return bind(lb, curry(f)); | |
460 } | |
461 | |
462 /** | |
463 * Promotes the given function of arity-2 to a function on lists. | |
464 * | |
465 * @param f The function to promote to a function on lists. | |
466 * @return The given function, promoted to operate on lists. | |
467 */ | |
468 public static <A, B, C> F<List<A>, F<List<B>, List<C>>> liftM2(final F<A, F<B, C>> f) { | |
469 return curry(new F2<List<A>, List<B>, List<C>>() { | |
470 public List<C> f(final List<A> as, final List<B> bs) { | |
471 return as.bind(bs, f); | |
472 } | |
473 }); | |
474 } | |
475 | |
476 /** | |
477 * Binds the given function across each element of this list and the given lists with a final | |
478 * join. | |
479 * | |
480 * @param lb A given list to bind the given function with. | |
481 * @param lc A given list to bind the given function with. | |
482 * @param f The function to apply to each element of this list and the given lists. | |
483 * @return A new list after performing the map, then final join. | |
484 */ | |
485 public final <B, C, D> List<D> bind(final List<B> lb, final List<C> lc, final F<A, F<B, F<C, D>>> f) { | |
486 return lc.apply(bind(lb, f)); | |
487 } | |
488 | |
489 /** | |
490 * Binds the given function across each element of this list and the given lists with a final | |
491 * join. | |
492 * | |
493 * @param lb A given list to bind the given function with. | |
494 * @param lc A given list to bind the given function with. | |
495 * @param ld A given list to bind the given function with. | |
496 * @param f The function to apply to each element of this list and the given lists. | |
497 * @return A new list after performing the map, then final join. | |
498 */ | |
499 public final <B, C, D, E> List<E> bind(final List<B> lb, final List<C> lc, final List<D> ld, | |
500 final F<A, F<B, F<C, F<D, E>>>> f) { | |
501 return ld.apply(bind(lb, lc, f)); | |
502 } | |
503 | |
504 /** | |
505 * Binds the given function across each element of this list and the given lists with a final | |
506 * join. | |
507 * | |
508 * @param lb A given list to bind the given function with. | |
509 * @param lc A given list to bind the given function with. | |
510 * @param ld A given list to bind the given function with. | |
511 * @param le A given list to bind the given function with. | |
512 * @param f The function to apply to each element of this list and the given lists. | |
513 * @return A new list after performing the map, then final join. | |
514 */ | |
515 public final <B, C, D, E, F$> List<F$> bind(final List<B> lb, final List<C> lc, final List<D> ld, final List<E> le, | |
516 final F<A, F<B, F<C, F<D, F<E, F$>>>>> f) { | |
517 return le.apply(bind(lb, lc, ld, f)); | |
518 } | |
519 | |
520 /** | |
521 * Binds the given function across each element of this list and the given lists with a final | |
522 * join. | |
523 * | |
524 * @param lb A given list to bind the given function with. | |
525 * @param lc A given list to bind the given function with. | |
526 * @param ld A given list to bind the given function with. | |
527 * @param le A given list to bind the given function with. | |
528 * @param lf A given list to bind the given function with. | |
529 * @param f The function to apply to each element of this list and the given lists. | |
530 * @return A new list after performing the map, then final join. | |
531 */ | |
532 public final <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, | |
533 final List<F$> lf, final F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>> f) { | |
534 return lf.apply(bind(lb, lc, ld, le, f)); | |
535 } | |
536 | |
537 /** | |
538 * Binds the given function across each element of this list and the given lists with a final | |
539 * join. | |
540 * | |
541 * @param lb A given list to bind the given function with. | |
542 * @param lc A given list to bind the given function with. | |
543 * @param ld A given list to bind the given function with. | |
544 * @param le A given list to bind the given function with. | |
545 * @param lf A given list to bind the given function with. | |
546 * @param lg A given list to bind the given function with. | |
547 * @param f The function to apply to each element of this list and the given lists. | |
548 * @return A new list after performing the map, then final join. | |
549 */ | |
550 public final <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, | |
551 final List<F$> lf, final List<G> lg, | |
552 final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>> f) { | |
553 return lg.apply(bind(lb, lc, ld, le, lf, f)); | |
554 } | |
555 | |
556 /** | |
557 * Binds the given function across each element of this list and the given lists with a final | |
558 * join. | |
559 * | |
560 * @param lb A given list to bind the given function with. | |
561 * @param lc A given list to bind the given function with. | |
562 * @param ld A given list to bind the given function with. | |
563 * @param le A given list to bind the given function with. | |
564 * @param lf A given list to bind the given function with. | |
565 * @param lg A given list to bind the given function with. | |
566 * @param lh A given list to bind the given function with. | |
567 * @param f The function to apply to each element of this list and the given lists. | |
568 * @return A new list after performing the map, then final join. | |
569 */ | |
570 public final <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, | |
571 final List<F$> lf, final List<G> lg, final List<H> lh, | |
572 final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>> f) { | |
573 return lh.apply(bind(lb, lc, ld, le, lf, lg, f)); | |
574 } | |
575 | |
576 /** | |
577 * Performs a bind across each list element, but ignores the element value each time. | |
578 * | |
579 * @param bs The list to apply in the final join. | |
580 * @return A new list after the final join. | |
581 */ | |
582 public final <B> List<B> sequence(final List<B> bs) { | |
583 final F<A, List<B>> c = constant(bs); | |
584 return bind(c); | |
585 } | |
586 | |
587 /** | |
588 * Performs function application within a list (applicative functor pattern). | |
589 * | |
590 * @param lf The list of functions to apply. | |
591 * @return A new list after applying the given list of functions through this list. | |
592 */ | |
593 public final <B> List<B> apply(final List<F<A, B>> lf) { | |
594 return lf.bind(new F<F<A, B>, List<B>>() { | |
595 public List<B> f(final F<A, B> f) { | |
596 return map(f); | |
597 } | |
598 }); | |
599 } | |
600 | |
601 /** | |
602 * Appends the given list to this list. | |
603 * | |
604 * @param as The list to append to this one. | |
605 * @return A new list that has appended the given list. | |
606 */ | |
607 public final List<A> append(final List<A> as) { | |
608 return fromList(this).append(as).toList(); | |
609 } | |
610 | |
611 /** | |
612 * Performs a right-fold reduction across this list. This function uses O(length) stack space. | |
613 * | |
614 * @param f The function to apply on each element of the list. | |
615 * @param b The beginning value to start the application from. | |
616 * @return The final result after the right-fold reduction. | |
617 */ | |
618 public final <B> B foldRight(final F<A, F<B, B>> f, final B b) { | |
619 return isEmpty() ? b : f.f(head()).f(tail().foldRight(f, b)); | |
620 } | |
621 | |
622 /** | |
623 * Performs a right-fold reduction across this list. This function uses O(length) stack space. | |
624 * | |
625 * @param f The function to apply on each element of the list. | |
626 * @param b The beginning value to start the application from. | |
627 * @return The final result after the right-fold reduction. | |
628 */ | |
629 public final <B> B foldRight(final F2<A, B, B> f, final B b) { | |
630 return foldRight(curry(f), b); | |
631 } | |
632 | |
633 /** | |
634 * Performs a right-fold reduction across this list in O(1) stack space. | |
635 * @param f The function to apply on each element of the list. | |
636 * @param b The beginning value to start the application from. | |
637 * @return A Trampoline containing the final result after the right-fold reduction. | |
638 */ | |
639 public final <B> Trampoline<B> foldRightC(final F2<A, B, B> f, final B b) { | |
640 return Trampoline.suspend(new P1<Trampoline<B>>() { | |
641 public Trampoline<B> _1() { | |
642 return isEmpty() ? Trampoline.pure(b) : tail().foldRightC(f, b).map(F2Functions.f(f, head())); | |
643 } | |
644 }); | |
645 } | |
646 | |
647 /** | |
648 * Performs a left-fold reduction across this list. This function runs in constant space. | |
649 * | |
650 * @param f The function to apply on each element of the list. | |
651 * @param b The beginning value to start the application from. | |
652 * @return The final result after the left-fold reduction. | |
653 */ | |
654 public final <B> B foldLeft(final F<B, F<A, B>> f, final B b) { | |
655 B x = b; | |
656 | |
657 for (List<A> xs = this; !xs.isEmpty(); xs = xs.tail()) { | |
658 x = f.f(x).f(xs.head()); | |
659 } | |
660 | |
661 return x; | |
662 } | |
663 | |
664 /** | |
665 * Performs a left-fold reduction across this list. This function runs in constant space. | |
666 * | |
667 * @param f The function to apply on each element of the list. | |
668 * @param b The beginning value to start the application from. | |
669 * @return The final result after the left-fold reduction. | |
670 */ | |
671 public final <B> B foldLeft(final F2<B, A, B> f, final B b) { | |
672 return foldLeft(curry(f), b); | |
673 } | |
674 | |
675 /** | |
676 * Takes the first 2 elements of the list and applies the function to them, | |
677 * then applies the function to the result and the third element and so on. | |
678 * | |
679 * @param f The function to apply on each element of the list. | |
680 * @return The final result after the left-fold reduction. | |
681 */ | |
682 public final A foldLeft1(final F2<A, A, A> f) { | |
683 return foldLeft1(curry(f)); | |
684 } | |
685 | |
686 /** | |
687 * Takes the first 2 elements of the list and applies the function to them, | |
688 * then applies the function to the result and the third element and so on. | |
689 * | |
690 * @param f The function to apply on each element of the list. | |
691 * @return The final result after the left-fold reduction. | |
692 */ | |
693 public final A foldLeft1(final F<A, F<A, A>> f) { | |
694 if (isEmpty()) | |
695 throw error("Undefined: foldLeft1 on empty list"); | |
696 return tail().foldLeft(f, head()); | |
697 } | |
698 | |
699 /** | |
700 * Reverse this list in constant stack space. | |
701 * | |
702 * @return A new list that is the reverse of this one. | |
703 */ | |
704 public final List<A> reverse() { | |
705 return foldLeft(new F<List<A>, F<A, List<A>>>() { | |
706 public F<A, List<A>> f(final List<A> as) { | |
707 return new F<A, List<A>>() { | |
708 public List<A> f(final A a) { | |
709 return cons(a, as); | |
710 } | |
711 }; | |
712 } | |
713 }, List.<A>nil()); | |
714 } | |
715 | |
716 /** | |
717 * Returns the element at the given index if it exists, fails otherwise. | |
718 * | |
719 * @param i The index at which to get the element to return. | |
720 * @return The element at the given index if it exists, fails otherwise. | |
721 */ | |
722 public final A index(final int i) { | |
723 if (i < 0 || i > length() - 1) | |
724 throw error("index " + i + " out of range on list with length " + length()); | |
725 else { | |
726 List<A> xs = this; | |
727 | |
728 for (int c = 0; c < i; c++) { | |
729 xs = xs.tail(); | |
730 } | |
731 | |
732 return xs.head(); | |
733 } | |
734 } | |
735 | |
736 /** | |
737 * Takes the given number of elements from the head of this list if they are available. | |
738 * | |
739 * @param i The maximum number of elements to take from this list. | |
740 * @return A new list with a length the same, or less than, this list. | |
741 */ | |
742 public final List<A> take(final int i) { | |
743 return i <= 0 || isEmpty() ? List.<A>nil() : cons(head(), tail().take(i - 1)); | |
744 } | |
745 | |
746 /** | |
747 * Drops the given number of elements from the head of this list if they are available. | |
748 * | |
749 * @param i The number of elements to drop from the head of this list. | |
750 * @return A list with a length the same, or less than, this list. | |
751 */ | |
752 public final List<A> drop(final int i) { | |
753 int c = 0; | |
754 | |
755 List<A> xs = this; | |
756 | |
757 for (; xs.isNotEmpty() && c < i; xs = xs.tail()) | |
758 c++; | |
759 | |
760 return xs; | |
761 } | |
762 | |
763 /** | |
764 * Splits this list into two lists at the given index. If the index goes out of bounds, then it is | |
765 * normalised so that this function never fails. | |
766 * | |
767 * @param i The index at which to split this list in two parts. | |
768 * @return A pair of lists split at the given index of this list. | |
769 */ | |
770 public final P2<List<A>, List<A>> splitAt(final int i) { | |
771 P2<List<A>, List<A>> s = p(List.<A>nil(), List.<A>nil()); | |
772 | |
773 int c = 0; | |
774 for (List<A> xs = this; xs.isNotEmpty(); xs = xs.tail()) { | |
775 final A h = xs.head(); | |
776 s = c < i ? s.map1(new F<List<A>, List<A>>() { | |
777 public List<A> f(final List<A> as) { | |
778 return as.snoc(h); | |
779 } | |
780 }) : s.map2(new F<List<A>, List<A>>() { | |
781 public List<A> f(final List<A> as) { | |
782 return as.snoc(h); | |
783 } | |
784 }); | |
785 c++; | |
786 } | |
787 | |
788 return s; | |
789 } | |
790 | |
791 /** | |
792 * Splits this list into lists of the given size. If the size of this list is not evenly divisible by | |
793 * the given number, the last partition will contain the remainder. | |
794 * | |
795 * @param n The size of the partitions into which to split this list. | |
796 * @return A list of sublists of this list, of at most the given size. | |
797 */ | |
798 public final List<List<A>> partition(final int n) { | |
799 if (n < 1) | |
800 throw error("Can't create list partitions shorter than 1 element long."); | |
801 if (isEmpty()) | |
802 throw error("Partition on empty list."); | |
803 return unfold(new F<List<A>, Option<P2<List<A>, List<A>>>>() { | |
804 public Option<P2<List<A>, List<A>>> f(final List<A> as) { | |
805 return as.isEmpty() ? Option.<P2<List<A>, List<A>>>none() : some(as.splitAt(n)); | |
806 } | |
807 }, this); | |
808 } | |
809 | |
810 /** | |
811 * Returns the list of initial segments of this list, shortest first. | |
812 * | |
813 * @return The list of initial segments of this list, shortest first. | |
814 */ | |
815 public final List<List<A>> inits() { | |
816 List<List<A>> s = single(List.<A>nil()); | |
817 if (isNotEmpty()) | |
818 s = s.append(tail().inits().map(List.<A>cons().f(head()))); | |
819 return s; | |
820 } | |
821 | |
822 /** | |
823 * Returns the list of final segments of this list, longest first. | |
824 * | |
825 * @return The list of final segments of this list, longest first. | |
826 */ | |
827 public final List<List<A>> tails() { | |
828 return isEmpty() ? single(List.<A>nil()) : cons(this, tail().tails()); | |
829 } | |
830 | |
831 /** | |
832 * Sorts this list using the given order over elements using a <em>merge sort</em> algorithm. | |
833 * | |
834 * @param o The order over the elements of this list. | |
835 * @return A sorted list according to the given order. | |
836 */ | |
837 public final List<A> sort(final Ord<A> o) { | |
838 if (isEmpty()) | |
839 return nil(); | |
840 else if (tail().isEmpty()) | |
841 return this; | |
842 else { | |
843 final class Merge<A> { | |
844 List<A> merge(List<A> xs, List<A> ys, final Ord<A> o) { | |
845 final Buffer<A> buf = empty(); | |
846 | |
847 while (true) { | |
848 if (xs.isEmpty()) { | |
849 buf.append(ys); | |
850 break; | |
851 } | |
852 | |
853 if (ys.isEmpty()) { | |
854 buf.append(xs); | |
855 break; | |
856 } | |
857 | |
858 final A x = xs.head(); | |
859 final A y = ys.head(); | |
860 | |
861 if (o.isLessThan(x, y)) { | |
862 buf.snoc(x); | |
863 xs = xs.tail(); | |
864 } else { | |
865 buf.snoc(y); | |
866 ys = ys.tail(); | |
867 } | |
868 } | |
869 | |
870 return buf.toList(); | |
871 } | |
872 } | |
873 | |
874 final P2<List<A>, List<A>> s = splitAt(length() / 2); | |
875 return new Merge<A>().merge(s._1().sort(o), s._2().sort(o), o); | |
876 } | |
877 } | |
878 | |
879 /** | |
880 * Zips this list with the given list using the given function to produce a new list. If this list | |
881 * and the given list have different lengths, then the longer list is normalised so this function | |
882 * never fails. | |
883 * | |
884 * @param bs The list to zip this list with. | |
885 * @param f The function to zip this list and the given list with. | |
886 * @return A new list with a length the same as the shortest of this list and the given list. | |
887 */ | |
888 public final <B, C> List<C> zipWith(List<B> bs, final F<A, F<B, C>> f) { | |
889 final Buffer<C> buf = empty(); | |
890 List<A> as = this; | |
891 | |
892 while (as.isNotEmpty() && bs.isNotEmpty()) { | |
893 buf.snoc(f.f(as.head()).f(bs.head())); | |
894 as = as.tail(); | |
895 bs = bs.tail(); | |
896 } | |
897 | |
898 return buf.toList(); | |
899 } | |
900 | |
901 /** | |
902 * Zips this list with the given list using the given function to produce a new list. If this list | |
903 * and the given list have different lengths, then the longer list is normalised so this function | |
904 * never fails. | |
905 * | |
906 * @param bs The list to zip this list with. | |
907 * @param f The function to zip this list and the given list with. | |
908 * @return A new list with a length the same as the shortest of this list and the given list. | |
909 */ | |
910 public final <B, C> List<C> zipWith(final List<B> bs, final F2<A, B, C> f) { | |
911 return zipWith(bs, curry(f)); | |
912 } | |
913 | |
914 /** | |
915 * Provides a first-class version of zipWith | |
916 * | |
917 * @return The first-class version of zipWith | |
918 */ | |
919 public static <A, B, C> F<List<A>, F<List<B>, F<F<A, F<B, C>>, List<C>>>> zipWith() { | |
920 return curry(new F3<List<A>, List<B>, F<A, F<B, C>>, List<C>>() { | |
921 public List<C> f(final List<A> as, final List<B> bs, final F<A, F<B, C>> f) { | |
922 return as.zipWith(bs, f); | |
923 } | |
924 }); | |
925 } | |
926 | |
927 /** | |
928 * Zips this list with the given list to produce a list of pairs. If this list and the given list | |
929 * have different lengths, then the longer list is normalised so this function never fails. | |
930 * | |
931 * @param bs The list to zip this list with. | |
932 * @return A new list with a length the same as the shortest of this list and the given list. | |
933 */ | |
934 public final <B> List<P2<A, B>> zip(final List<B> bs) { | |
935 final F<A, F<B, P2<A, B>>> __2 = p2(); | |
936 return zipWith(bs, __2); | |
937 } | |
938 | |
939 /** | |
940 * The first-class version of the zip function. | |
941 * | |
942 * @return A function that zips the given lists to produce a list of pairs. | |
943 */ | |
944 public static <A, B> F<List<A>, F<List<B>, List<P2<A, B>>>> zip() { | |
945 return curry(new F2<List<A>, List<B>, List<P2<A, B>>>() { | |
946 public List<P2<A, B>> f(final List<A> as, final List<B> bs) { | |
947 return as.zip(bs); | |
948 } | |
949 }); | |
950 } | |
951 | |
952 /** | |
953 * Zips this list with the index of its element as a pair. | |
954 * | |
955 * @return A new list with the same length as this list. | |
956 */ | |
957 public final List<P2<A, Integer>> zipIndex() { | |
958 return zipWith(range(0, length()), new F<A, F<Integer, P2<A, Integer>>>() { | |
959 public F<Integer, P2<A, Integer>> f(final A a) { | |
960 return new F<Integer, P2<A, Integer>>() { | |
961 public P2<A, Integer> f(final Integer i) { | |
962 return p(a, i); | |
963 } | |
964 }; | |
965 } | |
966 }); | |
967 } | |
968 | |
969 /** | |
970 * Appends (snoc) the given element to this list to produce a new list. | |
971 * | |
972 * @param a The element to append to this list. | |
973 * @return A new list with the given element appended. | |
974 */ | |
975 public final List<A> snoc(final A a) { | |
976 return fromList(this).snoc(a).toList(); | |
977 } | |
978 | |
979 /** | |
980 * Returns <code>true</code> if the predicate holds for all of the elements of this list, | |
981 * <code>false</code> otherwise (<code>true</code> for the empty list). | |
982 * | |
983 * @param f The predicate function to test on each element of this list. | |
984 * @return <code>true</code> if the predicate holds for all of the elements of this list, | |
985 * <code>false</code> otherwise. | |
986 */ | |
987 public final boolean forall(final F<A, Boolean> f) { | |
988 return isEmpty() || f.f(head()) && tail().forall(f); | |
989 } | |
990 | |
991 /** | |
992 * Returns <code>true</code> if the predicate holds for at least one of the elements of this list, | |
993 * <code>false</code> otherwise (<code>false</code> for the empty list). | |
994 * | |
995 * @param f The predicate function to test on the elements of this list. | |
996 * @return <code>true</code> if the predicate holds for at least one of the elements of this | |
997 * list. | |
998 */ | |
999 public final boolean exists(final F<A, Boolean> f) { | |
1000 return find(f).isSome(); | |
1001 } | |
1002 | |
1003 /** | |
1004 * Finds the first occurrence of an element that matches the given predicate or no value if no | |
1005 * elements match. | |
1006 * | |
1007 * @param f The predicate function to test on elements of this list. | |
1008 * @return The first occurrence of an element that matches the given predicate or no value if no | |
1009 * elements match. | |
1010 */ | |
1011 public final Option<A> find(final F<A, Boolean> f) { | |
1012 for (List<A> as = this; as.isNotEmpty(); as = as.tail()) { | |
1013 if (f.f(as.head())) | |
1014 return some(as.head()); | |
1015 } | |
1016 | |
1017 return none(); | |
1018 } | |
1019 | |
1020 /** | |
1021 * Intersperses the given argument between each element of this list. | |
1022 * | |
1023 * @param a The separator to intersperse in this list. | |
1024 * @return A list with the given separator interspersed. | |
1025 */ | |
1026 public final List<A> intersperse(final A a) { | |
1027 return isEmpty() || tail().isEmpty() ? | |
1028 this : | |
1029 cons(head(), cons(a, tail().intersperse(a))); | |
1030 } | |
1031 | |
1032 /** | |
1033 * Intersperses this list through the given list then joins the results. | |
1034 * | |
1035 * @param as The list to intersperse through. | |
1036 * @return This list through the given list then joins the results. | |
1037 */ | |
1038 @SuppressWarnings({"unchecked"}) | |
1039 public final List<A> intercalate(final List<List<A>> as) { | |
1040 return join(as.intersperse(this)); | |
1041 } | |
1042 | |
1043 /** | |
1044 * Removes duplicates according to object equality. | |
1045 * | |
1046 * @return A list without duplicates according to object equality. | |
1047 */ | |
1048 public final List<A> nub() { | |
1049 return nub(Equal.<A>anyEqual()); | |
1050 } | |
1051 | |
1052 /** | |
1053 * Removes duplicates according to the given equality. Warning: O(n^2). | |
1054 * | |
1055 * @param eq Equality over the elements. | |
1056 * @return A list without duplicates. | |
1057 */ | |
1058 public final List<A> nub(final Equal<A> eq) { | |
1059 return isEmpty() ? this : cons(head(), tail().filter(new F<A, Boolean>() { | |
1060 public Boolean f(final A a) { | |
1061 return !eq.eq(a, head()); | |
1062 } | |
1063 }).nub(eq)); | |
1064 } | |
1065 | |
1066 /** | |
1067 * Removes duplicates according to the given ordering. This function is O(n). | |
1068 * | |
1069 * @param o An ordering for the elements. | |
1070 * @return A list without duplicates. | |
1071 */ | |
1072 @SuppressWarnings({"unchecked"}) | |
1073 public final List<A> nub(final Ord<A> o) { | |
1074 return sort(o).group(o.equal()).map(List.<A>head_()); | |
1075 } | |
1076 | |
1077 /** | |
1078 * First-class head function. | |
1079 * | |
1080 * @return A function that gets the head of a given list. | |
1081 */ | |
1082 public static <A> F<List<A>, A> head_() { | |
1083 return new F<List<A>, A>() { | |
1084 public A f(final List<A> list) { | |
1085 return list.head(); | |
1086 } | |
1087 }; | |
1088 } | |
1089 | |
1090 /** | |
1091 * First-class tail function. | |
1092 * | |
1093 * @return A function that gets the tail of a given list. | |
1094 */ | |
1095 public static <A> F<List<A>, List<A>> tail_() { | |
1096 return new F<List<A>, List<A>>() { | |
1097 public List<A> f(final List<A> list) { | |
1098 return list.tail(); | |
1099 } | |
1100 }; | |
1101 } | |
1102 | |
1103 /** | |
1104 * Returns a new list of all the items in this list that do not appear in the given list. | |
1105 * | |
1106 * @param eq an equality for the items of the lists. | |
1107 * @param xs a list to subtract from this list. | |
1108 * @return a list of all the items in this list that do not appear in the given list. | |
1109 */ | |
1110 public final List<A> minus(final Equal<A> eq, final List<A> xs) { | |
1111 return removeAll(compose(Monoid.disjunctionMonoid.sumLeft(), xs.mapM(curry(eq.eq())))); | |
1112 } | |
1113 | |
1114 /** | |
1115 * Maps the given function of arity-2 across this list and returns a function that applies all the resulting | |
1116 * functions to a given argument. | |
1117 * | |
1118 * @param f A function of arity-2 | |
1119 * @return A function that, when given an argument, applies the given function to that argument and every element | |
1120 * in this list. | |
1121 */ | |
1122 public final <B, C> F<B, List<C>> mapM(final F<A, F<B, C>> f) { | |
1123 return sequence_(map(f)); | |
1124 } | |
1125 | |
1126 /** | |
1127 * Maps the given function across this list by binding through the Option monad. | |
1128 * | |
1129 * @param f The function to apply through the this list. | |
1130 * @return A possible list of values after binding through the Option monad. | |
1131 */ | |
1132 public final <B> Option<List<B>> mapMOption(final F<A, Option<B>> f) { | |
1133 return foldRight(new F2<A, Option<List<B>>, Option<List<B>>>() { | |
1134 public Option<List<B>> f(final A a, final Option<List<B>> bs) { | |
1135 return f.f(a).bind(new F<B, Option<List<B>>>() { | |
1136 public Option<List<B>> f(final B b) { | |
1137 return bs.map(new F<List<B>, List<B>>() { | |
1138 public List<B> f(final List<B> bbs) { | |
1139 return bbs.cons(b); | |
1140 } | |
1141 }); | |
1142 } | |
1143 }); | |
1144 } | |
1145 }, Option.<List<B>>some(List.<B>nil())); | |
1146 } | |
1147 | |
1148 /** | |
1149 * Maps the given function across this list by binding through the Trampoline monad. | |
1150 * | |
1151 * @param f The function to apply through the this list. | |
1152 * @return A list of values in the Trampoline monad. | |
1153 */ | |
1154 public final <B> Trampoline<List<B>> mapMTrampoline(final F<A, Trampoline<B>> f) { | |
1155 return foldRight(new F2<A, Trampoline<List<B>>, Trampoline<List<B>>>() { | |
1156 public Trampoline<List<B>> f(final A a, final Trampoline<List<B>> bs) { | |
1157 return f.f(a).bind(new F<B, Trampoline<List<B>>>() { | |
1158 public Trampoline<List<B>> f(final B b) { | |
1159 return bs.map(new F<List<B>, List<B>>() { | |
1160 public List<B> f(final List<B> bbs) { | |
1161 return bbs.cons(b); | |
1162 } | |
1163 }); | |
1164 } | |
1165 }); | |
1166 } | |
1167 }, Trampoline.<List<B>>pure(List.<B>nil())); | |
1168 } | |
1169 | |
1170 /** | |
1171 * Returns the index of the first element in this list which is equal (by the given equality) to the | |
1172 * query element, or None if there is no such element. | |
1173 * | |
1174 * @param e An equality for this list's elements. | |
1175 * @param a A query element. | |
1176 * @return The index of the first element in this list which is equal (by the given equality) to the | |
1177 * query element, or None if there is no such element. | |
1178 */ | |
1179 public final Option<Integer> elementIndex(final Equal<A> e, final A a) { | |
1180 return lookup(e, zipIndex(), a); | |
1181 } | |
1182 | |
1183 /** | |
1184 * Returns the last element of this list. Undefined for the empty list. | |
1185 * | |
1186 * @return The last element of this list or throws an error if this list is empty. | |
1187 */ | |
1188 public final A last() { | |
1189 A a = head(); | |
1190 for (List<A> xs = tail(); xs.isNotEmpty(); xs = xs.tail()) | |
1191 a = xs.head(); | |
1192 return a; | |
1193 } | |
1194 | |
1195 /** | |
1196 * Returns all but the last element of this list. Undefiend for the empty list. | |
1197 * | |
1198 * @return All but the last element of this list. Undefiend for the empty list. | |
1199 */ | |
1200 public final List<A> init() { | |
1201 List<A> ys = this; | |
1202 final Buffer<A> a = empty(); | |
1203 while(ys.isNotEmpty() && ys.tail().isNotEmpty()) { | |
1204 a.snoc(head()); | |
1205 ys = ys.tail(); | |
1206 } | |
1207 return a.toList(); | |
1208 } | |
1209 | |
1210 /** | |
1211 * Inserts the given element before the first element that is greater than or equal to it according | |
1212 * to the given ordering. | |
1213 * | |
1214 * @param f An ordering function to compare elements. | |
1215 * @param x The element to insert. | |
1216 * @return A new list with the given element inserted before the first element that is greater than or equal to | |
1217 * it according to the given ordering. | |
1218 */ | |
1219 public final List<A> insertBy(final F<A, F<A, Ordering>> f, final A x) { | |
1220 List<A> ys = this; | |
1221 Buffer<A> xs = empty(); | |
1222 while (ys.isNotEmpty() && f.f(x).f(ys.head()) == GT) { | |
1223 xs = xs.snoc(ys.head()); | |
1224 ys = ys.tail(); | |
1225 } | |
1226 return xs.append(ys.cons(x)).toList(); | |
1227 } | |
1228 | |
1229 /** | |
1230 * Returns the most common element in this list. | |
1231 * | |
1232 * @param o An ordering for the elements of the list. | |
1233 * @return The most common element in this list. | |
1234 */ | |
1235 public final A mode(final Ord<A> o) { | |
1236 return sort(o).group(o.equal()).maximum(intOrd.comap(List.<A>length_())).head(); | |
1237 } | |
1238 | |
1239 /** | |
1240 * Groups the elements of this list by a given keyFunction into a {@link TreeMap}. | |
1241 * The ordering of the keys is determined by {@link fj.Ord#hashOrd()}. | |
1242 * | |
1243 * @param keyFunction The function to select the keys for the map. | |
1244 * @return A TreeMap containing the keys with the accumulated list of matched elements. | |
1245 */ | |
1246 public final <B> TreeMap<B, List<A>> groupBy(final F<A, B> keyFunction) { | |
1247 return groupBy(keyFunction, Ord.hashOrd()); | |
1248 } | |
1249 | |
1250 /** | |
1251 * Groups the elements of this list by a given keyFunction into a {@link TreeMap}. | |
1252 * | |
1253 * @param keyFunction The function to select the keys for the map. | |
1254 * @param keyOrd An order for the keys of the tree map. | |
1255 * @return A TreeMap containing the keys with the accumulated list of matched elements. | |
1256 */ | |
1257 public final <B> TreeMap<B, List<A>> groupBy(final F<A, B> keyFunction, final Ord<B> keyOrd) { | |
1258 return groupBy(keyFunction, Function.identity(), keyOrd); | |
1259 } | |
1260 | |
1261 /** | |
1262 * Groups the elements of this list by a given keyFunction into a {@link TreeMap} and transforms | |
1263 * the matching elements with the given valueFunction. The ordering of the keys is determined by | |
1264 * {@link fj.Ord#hashOrd()}. | |
1265 * | |
1266 * @param keyFunction The function to select the keys for the map. | |
1267 * @param valueFunction The function to apply on each matching value. | |
1268 * @return A TreeMap containing the keys with the accumulated list of matched and mapped elements. | |
1269 */ | |
1270 public final <B, C> TreeMap<B, List<C>> groupBy( | |
1271 final F<A, B> keyFunction, | |
1272 final F<A, C> valueFunction) { | |
1273 return this.groupBy(keyFunction, valueFunction, Ord.hashOrd()); | |
1274 } | |
1275 | |
1276 /** | |
1277 * Groups the elements of this list by a given keyFunction into a {@link TreeMap} and transforms | |
1278 * the matching elements with the given valueFunction. The ordering of the keys is determined by | |
1279 * the keyOrd parameter. | |
1280 * | |
1281 * @param keyFunction The function to select the keys for the map. | |
1282 * @param valueFunction The function to apply on each matching value. | |
1283 * @param keyOrd An order for the keys of the tree map. | |
1284 * @return A TreeMap containing the keys with the accumulated list of matched and mapped elements. | |
1285 */ | |
1286 public final <B, C> TreeMap<B, List<C>> groupBy( | |
1287 final F<A, B> keyFunction, | |
1288 final F<A, C> valueFunction, | |
1289 final Ord<B> keyOrd) { | |
1290 return this.groupBy(keyFunction, valueFunction, List.<C>nil(), List::cons, keyOrd); | |
1291 } | |
1292 | |
1293 /** | |
1294 * Groups the elements of this list by a given keyFunction into a {@link TreeMap} and transforms | |
1295 * the matching elements with the given valueFunction. The ordering of the keys is determined by | |
1296 * the keyOrd parameter. | |
1297 * | |
1298 * @param keyFunction The function to select the keys for the map. | |
1299 * @param valueFunction The function to apply on each matching value. | |
1300 * @param monoid A monoid, which defines the accumulator for the values and the zero value. | |
1301 * @param keyOrd An order for the keys of the tree map. | |
1302 * @return A TreeMap containing the keys with the accumulated list of matched and mapped elements. | |
1303 */ | |
1304 public final <B, C> TreeMap<B, C> groupBy( | |
1305 final F<A, B> keyFunction, | |
1306 final F<A, C> valueFunction, | |
1307 final Monoid<C> monoid, | |
1308 final Ord<B> keyOrd) { | |
1309 return groupBy(keyFunction, valueFunction, monoid.zero(), | |
1310 Function.uncurryF2(monoid.sum()), keyOrd); | |
1311 } | |
1312 | |
1313 /** | |
1314 * Groups the elements of this list by a given keyFunction, applies the valueFunction and | |
1315 * accumulates the mapped values with the given grouping accumulator function on the grouping | |
1316 * identity. | |
1317 * | |
1318 * @param keyFunction The function to select the keys. | |
1319 * @param valueFunction The function to apply on each element. | |
1320 * @param groupingIdentity The identity, or start value, for the grouping. | |
1321 * @param groupingAcc The accumulator to apply on each matching value. | |
1322 * @param keyOrd An order for the keys of the tree map. | |
1323 * @return A TreeMap containing the keys with the accumulated result of matched and mapped | |
1324 * elements. | |
1325 */ | |
1326 public final <B, C, D> TreeMap<B, D> groupBy( | |
1327 final F<A, B> keyFunction, | |
1328 final F<A, C> valueFunction, | |
1329 final D groupingIdentity, | |
1330 final F2<C, D, D> groupingAcc, | |
1331 final Ord<B> keyOrd) { | |
1332 return this.foldLeft(map -> element -> { | |
1333 final B key = keyFunction.f(element); | |
1334 final C value = valueFunction.f(element); | |
1335 return map.set(key, map.get(key) | |
1336 .map(existing -> groupingAcc.f(value, existing)) | |
1337 .orSome(groupingAcc.f(value, groupingIdentity))); | |
1338 }, TreeMap.<B, D>empty(keyOrd) | |
1339 ); | |
1340 } | |
1341 | |
1342 | |
1343 | |
1344 /** | |
1345 * Returns whether or not all elements in the list are equal according to the given equality test. | |
1346 * | |
1347 * @param eq The equality test. | |
1348 * @return Whether or not all elements in the list are equal according to the given equality test. | |
1349 */ | |
1350 public boolean allEqual(final Equal<A> eq) { | |
1351 return isEmpty() || tail().isEmpty() || eq.eq(head(), tail().head()) && tail().allEqual(eq); | |
1352 } | |
1353 | |
1354 /** | |
1355 * First-class length. | |
1356 * | |
1357 * @return A function that gets the length of a given list. | |
1358 */ | |
1359 public static <A> F<List<A>, Integer> length_() { | |
1360 return new F<List<A>, Integer>() { | |
1361 public Integer f(final List<A> a) { | |
1362 return a.length(); | |
1363 } | |
1364 }; | |
1365 } | |
1366 | |
1367 /** | |
1368 * Returns the maximum element in this list according to the given ordering. | |
1369 * | |
1370 * @param o An ordering for the elements of the list. | |
1371 * @return The maximum element in this list according to the given ordering. | |
1372 */ | |
1373 public final A maximum(final Ord<A> o) { | |
1374 return foldLeft1(o.max); | |
1375 } | |
1376 | |
1377 /** | |
1378 * Returns the minimum element in this list according to the given ordering. | |
1379 * | |
1380 * @param o An ordering for the elements of the list. | |
1381 * @return The minimum element in this list according to the given ordering. | |
1382 */ | |
1383 public final A minimum(final Ord<A> o) { | |
1384 return foldLeft1(o.min); | |
1385 } | |
1386 | |
1387 /** | |
1388 * Projects an immutable collection of this list. | |
1389 * | |
1390 * @return An immutable collection of this list. | |
1391 */ | |
1392 public final Collection<A> toCollection() { | |
1393 return new AbstractCollection<A>() { | |
1394 public Iterator<A> iterator() { | |
1395 return new Iterator<A>() { | |
1396 private List<A> xs = List.this; | |
1397 | |
1398 public boolean hasNext() { | |
1399 return xs.isNotEmpty(); | |
1400 } | |
1401 | |
1402 public A next() { | |
1403 if (xs.isEmpty()) | |
1404 throw new NoSuchElementException(); | |
1405 else { | |
1406 final A a = xs.head(); | |
1407 xs = xs.tail(); | |
1408 return a; | |
1409 } | |
1410 } | |
1411 | |
1412 public void remove() { | |
1413 throw new UnsupportedOperationException(); | |
1414 } | |
1415 }; | |
1416 } | |
1417 | |
1418 public int size() { | |
1419 return length(); | |
1420 } | |
1421 }; | |
1422 } | |
1423 | |
1424 private static final class Nil<A> extends List<A> { | |
1425 public static final Nil<Object> INSTANCE = new Nil<Object>(); | |
1426 | |
1427 public A head() { | |
1428 throw error("head on empty list"); | |
1429 } | |
1430 | |
1431 public List<A> tail() { | |
1432 throw error("tail on empty list"); | |
1433 } | |
1434 } | |
1435 | |
1436 private static final class Cons<A> extends List<A> { | |
1437 private final A head; | |
1438 private List<A> tail; | |
1439 | |
1440 Cons(final A head, final List<A> tail) { | |
1441 this.head = head; | |
1442 this.tail = tail; | |
1443 } | |
1444 | |
1445 public A head() { | |
1446 return head; | |
1447 } | |
1448 | |
1449 public List<A> tail() { | |
1450 return tail; | |
1451 } | |
1452 | |
1453 private void tail(final List<A> tail) { | |
1454 this.tail = tail; | |
1455 } | |
1456 } | |
1457 | |
1458 /** | |
1459 * Constructs a list from the given elements. | |
1460 * | |
1461 * @param as The elements to construct a list with. | |
1462 * @return A list with the given elements. | |
1463 */ | |
1464 public static <A> List<A> list(final A... as) { | |
1465 return Array.array(as).toList(); | |
1466 } | |
1467 | |
1468 /** | |
1469 * Returns an empty list. | |
1470 * | |
1471 * @return An empty list. | |
1472 */ | |
1473 @SuppressWarnings("unchecked") | |
1474 public static <A> List<A> nil() { | |
1475 return (Nil<A>) Nil.INSTANCE; | |
1476 } | |
1477 | |
1478 /** | |
1479 * Returns a function that prepends (cons) an element to a list to produce a new list. | |
1480 * | |
1481 * @return A function that prepends (cons) an element to a list to produce a new list. | |
1482 */ | |
1483 public static <A> F<A, F<List<A>, List<A>>> cons() { | |
1484 return new F<A, F<List<A>, List<A>>>() { | |
1485 public F<List<A>, List<A>> f(final A a) { | |
1486 return new F<List<A>, List<A>>() { | |
1487 public List<A> f(final List<A> tail) { | |
1488 return cons(a, tail); | |
1489 } | |
1490 }; | |
1491 } | |
1492 }; | |
1493 } | |
1494 | |
1495 public static <A> F2<A, List<A>, List<A>> cons_() { | |
1496 return (a, listA) -> cons(a, listA); | |
1497 } | |
1498 | |
1499 /** | |
1500 * Returns a function that prepends a value to the given list. | |
1501 * | |
1502 * @param tail The list to prepend to. | |
1503 * @return A function that prepends a value to the given list. | |
1504 */ | |
1505 public static <A> F<A, List<A>> cons(final List<A> tail) { | |
1506 return new F<A, List<A>>() { | |
1507 public List<A> f(final A a) { | |
1508 return tail.cons(a); | |
1509 } | |
1510 }; | |
1511 } | |
1512 | |
1513 /** | |
1514 * Returns a function that prepends the given value to a list. | |
1515 * | |
1516 * @param a The value to prepend to a list. | |
1517 * @return A function that prepends the given value to a list. | |
1518 */ | |
1519 public static <A> F<List<A>, List<A>> cons_(final A a) { | |
1520 return new F<List<A>, List<A>>() { | |
1521 public List<A> f(final List<A> as) { | |
1522 return as.cons(a); | |
1523 } | |
1524 }; | |
1525 } | |
1526 | |
1527 /** | |
1528 * Prepends the given head element to the given tail element to produce a new list. | |
1529 * | |
1530 * @param head The element to prepend. | |
1531 * @param tail The list to prepend to. | |
1532 * @return The list with the given element prepended. | |
1533 */ | |
1534 public static <A> List<A> cons(final A head, final List<A> tail) { | |
1535 return new Cons<A>(head, tail); | |
1536 } | |
1537 | |
1538 /** | |
1539 * Returns a function that determines whether a given list is empty. | |
1540 * | |
1541 * @return A function that determines whether a given list is empty. | |
1542 */ | |
1543 public static <A> F<List<A>, Boolean> isEmpty_() { | |
1544 return new F<List<A>, Boolean>() { | |
1545 public Boolean f(final List<A> as) { | |
1546 return as.isEmpty(); | |
1547 } | |
1548 }; | |
1549 } | |
1550 | |
1551 /** | |
1552 * Returns a function that determines whether a given list is not empty. | |
1553 * | |
1554 * @return A function that determines whether a given list is not empty. | |
1555 */ | |
1556 public static <A> F<List<A>, Boolean> isNotEmpty_() { | |
1557 return new F<List<A>, Boolean>() { | |
1558 public Boolean f(final List<A> as) { | |
1559 return as.isNotEmpty(); | |
1560 } | |
1561 }; | |
1562 } | |
1563 | |
1564 /** | |
1565 * Joins the given list of lists using a bind operation. | |
1566 * | |
1567 * @param o The list of lists to join. | |
1568 * @return A new list that is the join of the given lists. | |
1569 */ | |
1570 public static <A> List<A> join(final List<List<A>> o) { | |
1571 final F<List<A>, List<A>> id = identity(); | |
1572 return o.bind(id); | |
1573 } | |
1574 | |
1575 /** | |
1576 * A first-class version of join | |
1577 * | |
1578 * @return A function that joins a list of lists using a bind operation. | |
1579 */ | |
1580 public static <A> F<List<List<A>>, List<A>> join() { | |
1581 return new F<List<List<A>>, List<A>>() { | |
1582 public List<A> f(final List<List<A>> as) { | |
1583 return join(as); | |
1584 } | |
1585 }; | |
1586 } | |
1587 | |
1588 /** | |
1589 * Unfolds across the given function starting at the given value to produce a list. | |
1590 * | |
1591 * @param f The function to unfold across. | |
1592 * @param b The start value to begin the unfold. | |
1593 * @return A new list that is a result of unfolding until the function does not produce a value. | |
1594 */ | |
1595 public static <A, B> List<A> unfold(final F<B, Option<P2<A, B>>> f, final B b) { | |
1596 Buffer<A> buf = empty(); | |
1597 for (Option<P2<A, B>> o = f.f(b); o.isSome(); o = f.f(o.some()._2())) { | |
1598 buf = buf.snoc(o.some()._1()); | |
1599 } | |
1600 return buf.toList(); | |
1601 } | |
1602 | |
1603 /** | |
1604 * Transforms a list of pairs into a list of first components and a list of second components. | |
1605 * | |
1606 * @param xs The list of pairs to transform.sp | |
1607 * @return A list of first components and a list of second components. | |
1608 */ | |
1609 public static <A, B> P2<List<A>, List<B>> unzip(final List<P2<A, B>> xs) { | |
1610 Buffer<A> ba = empty(); | |
1611 Buffer<B> bb = empty(); | |
1612 for (final P2<A, B> p : xs) { | |
1613 ba = ba.snoc(p._1()); | |
1614 bb = bb.snoc(p._2()); | |
1615 } | |
1616 return P.p(ba.toList(), bb.toList()); | |
1617 } | |
1618 | |
1619 /** | |
1620 * Returns a list of the given value replicated the given number of times. | |
1621 * | |
1622 * @param n The number of times to replicate the given value. | |
1623 * @param a The value to replicate. | |
1624 * @return A list of the given value replicated the given number of times. | |
1625 */ | |
1626 public static <A> List<A> replicate(final int n, final A a) { | |
1627 return n <= 0 ? List.<A>nil() : replicate(n - 1, a).cons(a); | |
1628 } | |
1629 | |
1630 /** | |
1631 * Returns a list of integers from the given <code>from</code> value (inclusive) to the given | |
1632 * <code>to</code> value (exclusive). | |
1633 * | |
1634 * @param from The minimum value for the list (inclusive). | |
1635 * @param to The maximum value for the list (exclusive). | |
1636 * @return A list of integers from the given <code>from</code> value (inclusive) to the given | |
1637 * <code>to</code> value (exclusive). | |
1638 */ | |
1639 public static List<Integer> range(final int from, final int to) { | |
1640 return from >= to ? List.<Integer>nil() : cons(from, range(from + 1, to)); | |
1641 } | |
1642 | |
1643 /** | |
1644 * Returns a list of characters from the given string. The inverse of this function is {@link | |
1645 * #asString(List)}. | |
1646 * | |
1647 * @param s The string to produce the list of characters from. | |
1648 * @return A list of characters from the given string. | |
1649 */ | |
1650 public static List<Character> fromString(final String s) { | |
1651 List<Character> cs = nil(); | |
1652 | |
1653 for (int i = s.length() - 1; i >= 0; i--) | |
1654 cs = cons(s.charAt(i), cs); | |
1655 | |
1656 return cs; | |
1657 } | |
1658 | |
1659 /** | |
1660 * A first-class <code>fromString</code>. | |
1661 * | |
1662 * @return A first-class <code>fromString</code>. | |
1663 */ | |
1664 public static F<String, List<Character>> fromString() { | |
1665 return new F<String, List<Character>>() { | |
1666 public List<Character> f(final String s) { | |
1667 return fromString(s); | |
1668 } | |
1669 }; | |
1670 } | |
1671 | |
1672 /** | |
1673 * Returns a string from the given list of characters. The invers of this function is {@link | |
1674 * #fromString(String)}. | |
1675 * | |
1676 * @param cs The list of characters to produce the string from. | |
1677 * @return A string from the given list of characters. | |
1678 */ | |
1679 public static String asString(final List<Character> cs) { | |
1680 final StringBuilder sb = new StringBuilder(); | |
1681 | |
1682 cs.foreach(new F<Character, Unit>() { | |
1683 public Unit f(final Character c) { | |
1684 sb.append(c); | |
1685 return unit(); | |
1686 } | |
1687 }); | |
1688 return sb.toString(); | |
1689 } | |
1690 | |
1691 /** | |
1692 * A first-class <code>asString</code>. | |
1693 * | |
1694 * @return A first-class <code>asString</code>. | |
1695 */ | |
1696 public static F<List<Character>, String> asString() { | |
1697 return new F<List<Character>, String>() { | |
1698 public String f(final List<Character> cs) { | |
1699 return asString(cs); | |
1700 } | |
1701 }; | |
1702 } | |
1703 | |
1704 /** | |
1705 * Returns a list of one element containing the given value. | |
1706 * | |
1707 * @param a The value for the head of the returned list. | |
1708 * @return A list of one element containing the given value. | |
1709 */ | |
1710 public static <A> List<A> single(final A a) { | |
1711 return cons(a, List.<A>nil()); | |
1712 } | |
1713 | |
1714 /** | |
1715 * Creates a list where the first item is calculated by applying the function on the third argument, | |
1716 * the second item by applying the function on the previous result and so on. | |
1717 * | |
1718 * @param f The function to iterate with. | |
1719 * @param p The predicate which must be true for the next item in order to continue the iteration. | |
1720 * @param a The input to the first iteration. | |
1721 * @return A list where the first item is calculated by applying the function on the third argument, | |
1722 * the second item by applying the function on the previous result and so on. | |
1723 */ | |
1724 public static <A> List<A> iterateWhile(final F<A, A> f, final F<A, Boolean> p, final A a) { | |
1725 return unfold( | |
1726 new F<A, Option<P2<A, A>>>() { | |
1727 public Option<P2<A, A>> f(final A o) { | |
1728 return Option.iif(new F<P2<A, A>, Boolean>() { | |
1729 public Boolean f(final P2<A, A> p2) { | |
1730 return p.f(o); | |
1731 } | |
1732 }, P.p(o, f.f(o))); | |
1733 } | |
1734 } | |
1735 , a); | |
1736 } | |
1737 | |
1738 /** | |
1739 * Returns an associated value with the given key in the list of pairs. | |
1740 * | |
1741 * @param e The test for equality on keys. | |
1742 * @param x The list of pairs to search. | |
1743 * @param a The key value to find the associated value of. | |
1744 * @return An associated value with the given key in the list of pairs. | |
1745 */ | |
1746 public static <A, B> Option<B> lookup(final Equal<A> e, final List<P2<A, B>> x, final A a) { | |
1747 return x.find(new F<P2<A, B>, Boolean>() { | |
1748 public Boolean f(final P2<A, B> p) { | |
1749 return e.eq(p._1(), a); | |
1750 } | |
1751 }).map(P2.<A, B>__2()); | |
1752 } | |
1753 | |
1754 /** | |
1755 * Returns a partially applied version of {@link #lookup(Equal, List, Object)}. | |
1756 * | |
1757 * @param e The test for equality on keys. | |
1758 * @return A partially applied version of {@link #lookup(Equal , List, Object)}. | |
1759 */ | |
1760 public static <A, B> F2<List<P2<A, B>>, A, Option<B>> lookup(final Equal<A> e) { | |
1761 return new F2<List<P2<A, B>>, A, Option<B>>() { | |
1762 public Option<B> f(final List<P2<A, B>> x, final A a) { | |
1763 return lookup(e, x, a); | |
1764 } | |
1765 }; | |
1766 } | |
1767 | |
1768 /** | |
1769 * Provides a first-class version of bind() | |
1770 * | |
1771 * @return The bind function for lists. | |
1772 */ | |
1773 public static <A, B> F<F<A, List<B>>, F<List<A>, List<B>>> bind_() { | |
1774 return curry(new F2<F<A, List<B>>, List<A>, List<B>>() { | |
1775 public List<B> f(final F<A, List<B>> f, final List<A> as) { | |
1776 return as.bind(f); | |
1777 } | |
1778 }); | |
1779 } | |
1780 | |
1781 /** | |
1782 * Provides a first-class version of map() | |
1783 * | |
1784 * @return The map function for lists. | |
1785 */ | |
1786 public static <A, B> F<F<A, B>, F<List<A>, List<B>>> map_() { | |
1787 return curry(new F2<F<A, B>, List<A>, List<B>>() { | |
1788 public List<B> f(final F<A, B> f, final List<A> as) { | |
1789 return as.map(f); | |
1790 } | |
1791 }); | |
1792 } | |
1793 | |
1794 /** | |
1795 * Turn a list of functions into a function returning a list. | |
1796 * | |
1797 * @param fs The list of functions to sequence into a single function that returns a list. | |
1798 * @return A function that, when given an argument, applies all the functions in the given list to it | |
1799 * and returns a list of the results. | |
1800 */ | |
1801 public static <A, B> F<B, List<A>> sequence_(final List<F<B, A>> fs) { | |
1802 return fs.foldRight(Function.<A, List<A>, List<A>, B>lift(List.<A>cons()), Function | |
1803 .<B, List<A>>constant(List.<A>nil())); | |
1804 } | |
1805 | |
1806 /** | |
1807 * Provides a first-class version of foldLeft. | |
1808 * | |
1809 * @return The left fold function for lists. | |
1810 */ | |
1811 public static <A, B> F<F<B, F<A, B>>, F<B, F<List<A>, B>>> foldLeft() { | |
1812 return curry(new F3<F<B, F<A, B>>, B, List<A>, B>() { | |
1813 public B f(final F<B, F<A, B>> f, final B b, final List<A> as) { | |
1814 return as.foldLeft(f, b); | |
1815 } | |
1816 }); | |
1817 } | |
1818 | |
1819 /** | |
1820 * Provides a first-class version of take. | |
1821 * | |
1822 * @return First-class version of take. | |
1823 */ | |
1824 public static <A> F<Integer, F<List<A>, List<A>>> take() { | |
1825 return curry(new F2<Integer, List<A>, List<A>>() { | |
1826 public List<A> f(final Integer n, final List<A> as) { | |
1827 return as.take(n); | |
1828 } | |
1829 }); | |
1830 } | |
1831 | |
1832 /** | |
1833 * Takes the given iterable to a list. | |
1834 * | |
1835 * @param i The iterable to take to a list. | |
1836 * @return A list from the given iterable. | |
1837 */ | |
1838 public static <A> List<A> iterableList(final Iterable<A> i) { | |
1839 final Buffer<A> bs = empty(); | |
1840 | |
1841 for (final A a : i) | |
1842 bs.snoc(a); | |
1843 | |
1844 return bs.toList(); | |
1845 } | |
1846 | |
1847 | |
1848 /** | |
1849 * A mutable, singly linked list. This structure should be used <em>very</em> sparingly, in favour | |
1850 * of the {@link List immutable singly linked list structure}. | |
1851 */ | |
1852 public static final class Buffer<A> implements Iterable<A> { | |
1853 private List<A> start = nil(); | |
1854 private Cons<A> tail; | |
1855 private boolean exported; | |
1856 | |
1857 /** | |
1858 * Returns an iterator for this buffer. This method exists to permit the use in a <code>for</code>-each loop. | |
1859 * | |
1860 * @return A iterator for this buffer. | |
1861 */ | |
1862 public Iterator<A> iterator() { | |
1863 return start.iterator(); | |
1864 } | |
1865 | |
1866 /** | |
1867 * Appends (snoc) the given element to this buffer to produce a new buffer. | |
1868 * | |
1869 * @param a The element to append to this buffer. | |
1870 * @return A new buffer with the given element appended. | |
1871 */ | |
1872 public Buffer<A> snoc(final A a) { | |
1873 if (exported) | |
1874 copy(); | |
1875 | |
1876 final Cons<A> t = new Cons<A>(a, List.<A>nil()); | |
1877 | |
1878 if (tail == null) | |
1879 start = t; | |
1880 else | |
1881 tail.tail(t); | |
1882 | |
1883 tail = t; | |
1884 | |
1885 return this; | |
1886 } | |
1887 | |
1888 /** | |
1889 * Appends the given buffer to this buffer. | |
1890 * | |
1891 * @param as The buffer to append to this one. | |
1892 * @return A new buffer that has appended the given buffer. | |
1893 */ | |
1894 public Buffer<A> append(final List<A> as) { | |
1895 for (List<A> xs = as; xs.isNotEmpty(); xs = xs.tail()) | |
1896 snoc(xs.head()); | |
1897 | |
1898 return this; | |
1899 } | |
1900 | |
1901 /** | |
1902 * Returns an immutable list projection of this buffer. Modifications to the underlying buffer | |
1903 * will <em>not</em> be reflected in returned lists. | |
1904 * | |
1905 * @return An immutable list projection of this buffer. | |
1906 */ | |
1907 public List<A> toList() { | |
1908 exported = !start.isEmpty(); | |
1909 return start; | |
1910 } | |
1911 | |
1912 /** | |
1913 * Projects an immutable collection of this buffer. | |
1914 * | |
1915 * @return An immutable collection of this buffer. | |
1916 */ | |
1917 public Collection<A> toCollection() { | |
1918 return start.toCollection(); | |
1919 } | |
1920 | |
1921 /** | |
1922 * An empty buffer. | |
1923 * | |
1924 * @return An empty buffer. | |
1925 */ | |
1926 public static <A> Buffer<A> empty() { | |
1927 return new Buffer<A>(); | |
1928 } | |
1929 | |
1930 /** | |
1931 * Constructs a buffer from the given list. | |
1932 * | |
1933 * @param as The list to construct a buffer with. | |
1934 * @return A buffer from the given list. | |
1935 */ | |
1936 public static <A> Buffer<A> fromList(final List<A> as) { | |
1937 final Buffer<A> b = new Buffer<A>(); | |
1938 | |
1939 for (List<A> xs = as; xs.isNotEmpty(); xs = xs.tail()) | |
1940 b.snoc(xs.head()); | |
1941 | |
1942 return b; | |
1943 } | |
1944 | |
1945 /** | |
1946 * Takes the given iterable to a buffer. | |
1947 * | |
1948 * @param i The iterable to take to a buffer. | |
1949 * @return A buffer from the given iterable. | |
1950 */ | |
1951 public static <A> Buffer<A> iterableBuffer(final Iterable<A> i) { | |
1952 final Buffer<A> b = empty(); | |
1953 | |
1954 for (final A a : i) | |
1955 b.snoc(a); | |
1956 | |
1957 return b; | |
1958 } | |
1959 | |
1960 @SuppressWarnings({"ObjectEquality"}) | |
1961 private void copy() { | |
1962 List<A> s = start; | |
1963 final Cons<A> t = tail; | |
1964 start = nil(); | |
1965 exported = false; | |
1966 while (s != t) { | |
1967 snoc(s.head()); | |
1968 s = s.tail(); | |
1969 } | |
1970 | |
1971 if (t != null) | |
1972 snoc(t.head()); | |
1973 } | |
1974 } | |
1975 | |
1976 /** | |
1977 * Perform an equality test on this list which delegates to the .equals() method of the member instances. | |
1978 * This is implemented with Equal.listEqual using the anyEqual rule. | |
1979 * | |
1980 * @param obj the other object to check for equality against. | |
1981 * @return true if this list is equal to the provided argument | |
1982 */ | |
1983 //Suppress the warning for cast to <code>List<A></code> because the type is checked in the previous line. | |
1984 @SuppressWarnings({ "unchecked" }) | |
1985 @Override public boolean equals( final Object obj ) { | |
1986 if ( obj == null || !( obj instanceof List ) ) { return false; } | |
1987 | |
1988 //Casting to List<A> here does not cause a runtime exception even if the type arguments don't match. | |
1989 //The cast is done to avoid the compiler warning "raw use of parameterized class 'List'" | |
1990 return Equal.listEqual( Equal.<A>anyEqual() ).eq( this, (List<A>) obj ); | |
1991 } | |
1992 | |
1993 /** | |
1994 * Compute the hash code from this list as a function of the hash codes of its members. | |
1995 * Delegates to Hash.listHash, using the anyHash() rule, which uses the hash codes of the contents. | |
1996 * | |
1997 * @return the hash code for this list. | |
1998 */ | |
1999 @Override public int hashCode() { | |
2000 return Hash.listHash( Hash.<A>anyHash() ).hash( this ); | |
2001 } | |
2002 | |
2003 /** | |
2004 * Obtain a string representation of this list using the toString implementations of the members. Uses Show.listShow with F2 argument and may | |
2005 * not be very performant. | |
2006 * | |
2007 * @return a String representation of the list | |
2008 */ | |
2009 @Override public String toString() { | |
2010 return Show.listShow( Show.<A>anyShow() ).show( this ).foldLeft( new F2<String, Character, String>() { | |
2011 @Override public String f( final String s, final Character c ) { | |
2012 return s + c; | |
2013 } | |
2014 }, "" ); | |
2015 } | |
2016 } |