comparison src/main/java/fj/Function.java @ 0:fe80c1edf1be

add getLoop
author tatsuki
date Fri, 20 Mar 2015 21:04:03 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:fe80c1edf1be
1 package fj;
2
3 import fj.data.Option;
4
5 /**
6 * Transformations on functions.
7 *
8 * @version %build.number%
9 */
10 public final class Function {
11 private Function() {
12 throw new UnsupportedOperationException();
13 }
14
15 /**
16 * Function application with the arguments flipped.
17 *
18 * @param a The value to apply the function to.
19 * @return A function that is partially-applied to the given value.
20 */
21 public static <A, B> F<F<A, B>, B> apply(final A a) {
22 return new F<F<A, B>, B>() {
23 public B f(final F<A, B> k) {
24 return k.f(a);
25 }
26 };
27 }
28
29 /**
30 * Function composition.
31 *
32 * @return A function that composes two functions to produce a new function.
33 */
34 public static <A, B, C> F<F<B, C>, F<F<A, B>, F<A, C>>> compose() {
35 return new F<F<B, C>, F<F<A, B>, F<A, C>>>() {
36 public F<F<A, B>, F<A, C>> f(final F<B, C> f) {
37 return new F<F<A, B>, F<A, C>>() {
38 public F<A, C> f(final F<A, B> g) {
39 return compose(f, g);
40 }
41 };
42 }
43 };
44 }
45
46 /**
47 * Function composition.
48 *
49 * @param f A function to compose with another.
50 * @param g A function to compose with another.
51 * @return A function that is the composition of the given arguments.
52 */
53 public static <A, B, C> F<A, C> compose(final F<B, C> f, final F<A, B> g) {
54 return new F<A, C>() {
55 public C f(final A a) {
56 return f.f(g.f(a));
57 }
58 };
59 }
60
61 /**
62 * Function composition.
63 *
64 * @param f A function to compose with another.
65 * @param g A function to compose with another.
66 * @return A function that is the composition of the given arguments.
67 */
68 public static <A, B, C, D> F<A, F<B, D>> compose2(final F<C, D> f, final F<A, F<B, C>> g) {
69 return new F<A, F<B, D>>() {
70 public F<B, D> f(final A a) {
71 return new F<B, D>() {
72 public D f(final B b) {
73 return f.f(g.f(a).f(b));
74 }
75 };
76 }
77 };
78 }
79
80
81 /**
82 * Function composition flipped.
83 *
84 * @return A function that composes two functions to produce a new function.
85 */
86 public static <A, B, C> F<F<A, B>, F<F<B, C>, F<A, C>>> andThen() {
87 return new F<F<A, B>, F<F<B, C>, F<A, C>>>() {
88 public F<F<B, C>, F<A, C>> f(final F<A, B> g) {
89 return new F<F<B, C>, F<A, C>>() {
90 public F<A, C> f(final F<B, C> f) {
91 return Function.andThen(g, f);
92 }
93 };
94 }
95 };
96 }
97
98 /**
99 * Function composition flipped.
100 *
101 * @param g A function to compose with another.
102 * @param f A function to compose with another.
103 * @return A function that is the composition of the given arguments.
104 */
105 public static <A, B, C> F<A, C> andThen(final F<A, B> g, final F<B, C> f) {
106 return new F<A, C>() {
107 public C f(final A a) {
108 return f.f(g.f(a));
109 }
110 };
111 }
112
113 /**
114 * The identity transformation.
115 *
116 * @return The identity transformation.
117 */
118 public static <A> F<A, A> identity() {
119 return new F<A, A>() {
120 public A f(final A a) {
121 return a;
122 }
123 };
124 }
125
126 /**
127 * Returns a function that given an argument, returns a function that ignores its argument.
128 *
129 * @return A function that given an argument, returns a function that ignores its argument.
130 */
131 public static <A, B> F<B, F<A, B>> constant() {
132 return new F<B, F<A, B>>() {
133 public F<A, B> f(final B b) {
134 return constant(b);
135 }
136 };
137 }
138
139 /**
140 * Returns a function that ignores its argument to constantly produce the given value.
141 *
142 * @param b The value to return when the returned function is applied.
143 * @return A function that ignores its argument to constantly produce the given value.
144 */
145 public static <A, B> F<A, B> constant(final B b) {
146 return new F<A, B>() {
147 public B f(final A a) {
148 return b;
149 }
150 };
151 }
152
153 /**
154 * Simultaneously covaries and contravaries a function.
155 *
156 * @param f The function to vary.
157 * @return A co- and contravariant function that invokes f on its argument.
158 */
159 public static <A, B> F<A, B> vary(final F<? super A, ? extends B> f) {
160 return new F<A, B>() {
161 public B f(final A a) {
162 return f.f(a);
163 }
164 };
165 }
166
167 /**
168 * Simultaneously covaries and contravaries a function.
169 *
170 * @return A function that varies and covaries a function.
171 */
172 public static <C, A extends C, B, D extends B> F<F<C, D>, F<A, B>> vary() {
173 return new F<F<C, D>, F<A, B>>() {
174 public F<A, B> f(final F<C, D> f) {
175 return Function.<A, B>vary(f);
176 }
177 };
178 }
179
180 /**
181 * Function argument flipping.
182 *
183 * @return A function that takes a function and flips its arguments.
184 */
185 public static <A, B, C> F<F<A, F<B, C>>, F<B, F<A, C>>> flip() {
186 return new F<F<A, F<B, C>>, F<B, F<A, C>>>() {
187 public F<B, F<A, C>> f(final F<A, F<B, C>> f) {
188 return flip(f);
189 }
190 };
191 }
192
193 /**
194 * Function argument flipping.
195 *
196 * @param f The function to flip.
197 * @return The given function flipped.
198 */
199 public static <A, B, C> F<B, F<A, C>> flip(final F<A, F<B, C>> f) {
200 return new F<B, F<A, C>>() {
201 public F<A, C> f(final B b) {
202 return new F<A, C>() {
203 public C f(final A a) {
204 return f.f(a).f(b);
205 }
206 };
207 }
208 };
209 }
210
211 /**
212 * Function argument flipping.
213 *
214 * @param f The function to flip.
215 * @return The given function flipped.
216 */
217 public static <A, B, C> F2<B, A, C> flip(final F2<A, B, C> f) {
218 return new F2<B, A, C>() {
219 public C f(final B b, final A a) {
220 return f.f(a, b);
221 }
222 };
223 }
224
225 /**
226 * Function argument flipping.
227 *
228 * @return A function that flips the arguments of a given function.
229 */
230 public static <A, B, C> F<F2<A, B, C>, F2<B, A, C>> flip2() {
231 return new F<F2<A, B, C>, F2<B, A, C>>() {
232 public F2<B, A, C> f(final F2<A, B, C> f) {
233 return flip(f);
234 }
235 };
236 }
237
238 /**
239 * Return a function that inspects the argument of the given function for a <code>null</code> value and if so, does
240 * not apply the value, instead returning an empty optional value.
241 *
242 * @param f The function to check for a <code>null</code> argument.
243 * @return A function that inspects the argument of the given function for a <code>null</code> value and if so, does
244 * not apply the value, instead returning an empty optional value.
245 */
246 public static <A, B> F<A, Option<B>> nullable(final F<A, B> f) {
247 return new F<A, Option<B>>() {
248 public Option<B> f(final A a) {
249 return a == null ? Option.<B>none() : Option.some(f.f(a));
250 }
251 };
252 }
253
254 /**
255 * Curry a function of arity-2.
256 *
257 * @param f The function to curry.
258 * @return A curried form of the given function.
259 */
260 public static <A, B, C> F<A, F<B, C>> curry(final F2<A, B, C> f) {
261 return new F<A, F<B, C>>() {
262 public F<B, C> f(final A a) {
263 return new F<B, C>() {
264 public C f(final B b) {
265 return f.f(a, b);
266 }
267 };
268 }
269 };
270 }
271
272 /**
273 * Curry a function of arity-2.
274 *
275 * @param f The function to curry.
276 * @param a An argument to the curried function.
277 * @return A curried form of the given function.
278 */
279 public static <A, B, C> F<B, C> curry(final F2<A, B, C> f, final A a) {
280 return curry(f).f(a);
281 }
282
283 /**
284 * Uncurry a function of arity-2.
285 *
286 * @return An uncurried function.
287 */
288 public static <A, B, C> F<F<A, F<B, C>>, F2<A, B, C>> uncurryF2() {
289 return new F<F<A, F<B, C>>, F2<A, B, C>>() {
290 public F2<A, B, C> f(final F<A, F<B, C>> f) {
291 return uncurryF2(f);
292 }
293 };
294 }
295
296 /**
297 * Uncurry a function of arity-2.
298 *
299 * @param f The function to uncurry.
300 * @return An uncurried function.
301 */
302 public static <A, B, C> F2<A, B, C> uncurryF2(final F<A, F<B, C>> f) {
303 return new F2<A, B, C>() {
304 public C f(final A a, final B b) {
305 return f.f(a).f(b);
306 }
307 };
308 }
309
310 /**
311 * Curry a function of arity-3.
312 *
313 * @param f The function to curry.
314 * @return A curried form of the given function.
315 */
316 public static <A, B, C, D> F<A, F<B, F<C, D>>> curry(final F3<A, B, C, D> f) {
317 return new F<A, F<B, F<C, D>>>() {
318 public F<B, F<C, D>> f(final A a) {
319 return new F<B, F<C, D>>() {
320 public F<C, D> f(final B b) {
321 return new F<C, D>() {
322 public D f(final C c) {
323 return f.f(a, b, c);
324 }
325 };
326 }
327 };
328 }
329 };
330 }
331
332 /**
333 * Curry a function of arity-3.
334 *
335 * @param f The function to curry.
336 * @param a An argument to the curried function.
337 * @return A curried form of the given function.
338 */
339 public static <A, B, C, D> F<B, F<C, D>> curry(final F3<A, B, C, D> f, final A a) {
340 return curry(f).f(a);
341 }
342
343 /**
344 * Curry a function of arity-3.
345 *
346 * @param f The function to curry.
347 * @param a An argument to the curried function.
348 * @param b An argument to the curried function.
349 * @return A curried form of the given function.
350 */
351 public static <A, B, C, D> F<C, D> curry(final F3<A, B, C, D> f, final A a, final B b) {
352 return curry(f, a).f(b);
353 }
354
355 /**
356 * Uncurry a function of arity-3.
357 *
358 * @return An uncurried function.
359 */
360 public static <A, B, C, D> F<F<A, F<B, F<C, D>>>, F3<A, B, C, D>> uncurryF3() {
361 return new F<F<A, F<B, F<C, D>>>, F3<A, B, C, D>>() {
362 public F3<A, B, C, D> f(final F<A, F<B, F<C, D>>> f) {
363 return uncurryF3(f);
364 }
365 };
366 }
367
368 /**
369 * Uncurry a function of arity-3.
370 *
371 * @param f The function to uncurry.
372 * @return An uncurried function.
373 */
374 public static <A, B, C, D> F3<A, B, C, D> uncurryF3(final F<A, F<B, F<C, D>>> f) {
375 return new F3<A, B, C, D>() {
376 public D f(final A a, final B b, final C c) {
377 return f.f(a).f(b).f(c);
378 }
379 };
380 }
381
382 /**
383 * Curry a function of arity-4.
384 *
385 * @param f The function to curry.
386 * @return A curried form of the given function.
387 */
388 public static <A, B, C, D, E> F<A, F<B, F<C, F<D, E>>>> curry(final F4<A, B, C, D, E> f) {
389 return new F<A, F<B, F<C, F<D, E>>>>() {
390 public F<B, F<C, F<D, E>>> f(final A a) {
391 return new F<B, F<C, F<D, E>>>() {
392 public F<C, F<D, E>> f(final B b) {
393 return new F<C, F<D, E>>() {
394 public F<D, E> f(final C c) {
395 return new F<D, E>() {
396 public E f(final D d) {
397 return f.f(a, b, c, d);
398 }
399 };
400 }
401 };
402 }
403 };
404 }
405 };
406 }
407
408 /**
409 * Curry a function of arity-4.
410 *
411 * @param f The function to curry.
412 * @param a An argument to the curried function.
413 * @return A curried form of the given function.
414 */
415 public static <A, B, C, D, E> F<B, F<C, F<D, E>>> curry(final F4<A, B, C, D, E> f, final A a) {
416 return curry(f).f(a);
417 }
418
419 /**
420 * Curry a function of arity-4.
421 *
422 * @param f The function to curry.
423 * @param a An argument to the curried function.
424 * @param b An argument to the curried function.
425 * @return A curried form of the given function.
426 */
427 public static <A, B, C, D, E> F<C, F<D, E>> curry(final F4<A, B, C, D, E> f, final A a, final B b) {
428 return curry(f).f(a).f(b);
429 }
430
431 /**
432 * Curry a function of arity-4.
433 *
434 * @param f The function to curry.
435 * @param a An argument to the curried function.
436 * @param b An argument to the curried function.
437 * @param c An argument to the curried function.
438 * @return A curried form of the given function.
439 */
440 public static <A, B, C, D, E> F<D, E> curry(final F4<A, B, C, D, E> f, final A a, final B b, final C c) {
441 return curry(f).f(a).f(b).f(c);
442 }
443
444 /**
445 * Uncurry a function of arity-4.
446 *
447 * @return An uncurried function.
448 */
449 public static <A, B, C, D, E> F<F<A, F<B, F<C, F<D, E>>>>, F4<A, B, C, D, E>> uncurryF4() {
450 return new F<F<A, F<B, F<C, F<D, E>>>>, F4<A, B, C, D, E>>() {
451 public F4<A, B, C, D, E> f(final F<A, F<B, F<C, F<D, E>>>> f) {
452 return uncurryF4(f);
453 }
454 };
455 }
456
457 /**
458 * Uncurry a function of arity-4.
459 *
460 * @param f The function to uncurry.
461 * @return An uncurried function.
462 */
463 public static <A, B, C, D, E> F4<A, B, C, D, E> uncurryF4(final F<A, F<B, F<C, F<D, E>>>> f) {
464 return new F4<A, B, C, D, E>() {
465 public E f(final A a, final B b, final C c, final D d) {
466 return f.f(a).f(b).f(c).f(d);
467 }
468 };
469 }
470
471 /**
472 * Curry a function of arity-5.
473 *
474 * @param f The function to curry.
475 * @return A curried form of the given function.
476 */
477 public static <A, B, C, D, E, F$> F<A, F<B, F<C, F<D, F<E, F$>>>>> curry(final F5<A, B, C, D, E, F$> f) {
478 return new F<A, F<B, F<C, F<D, F<E, F$>>>>>() {
479 public F<B, F<C, F<D, F<E, F$>>>> f(final A a) {
480 return new F<B, F<C, F<D, F<E, F$>>>>() {
481 public F<C, F<D, F<E, F$>>> f(final B b) {
482 return new F<C, F<D, F<E, F$>>>() {
483 public F<D, F<E, F$>> f(final C c) {
484 return new F<D, F<E, F$>>() {
485 public F<E, F$> f(final D d) {
486 return new F<E, F$>() {
487 public F$ f(final E e) {
488 return f.f(a, b, c, d, e);
489 }
490 };
491 }
492 };
493 }
494 };
495 }
496 };
497 }
498 };
499 }
500
501 /**
502 * Curry a function of arity-5.
503 *
504 * @param f The function to curry.
505 * @param a An argument to the curried function.
506 * @return A curried form of the given function.
507 */
508 public static <A, B, C, D, E, F$> F<B, F<C, F<D, F<E, F$>>>> curry(final F5<A, B, C, D, E, F$> f, final A a) {
509 return curry(f).f(a);
510 }
511
512 /**
513 * Curry a function of arity-5.
514 *
515 * @param f The function to curry.
516 * @param a An argument to the curried function.
517 * @param b An argument to the curried function.
518 * @return A curried form of the given function.
519 */
520 public static <A, B, C, D, E, F$> F<C, F<D, F<E, F$>>> curry(final F5<A, B, C, D, E, F$> f, final A a, final B b) {
521 return curry(f).f(a).f(b);
522 }
523
524 /**
525 * Curry a function of arity-5.
526 *
527 * @param f The function to curry.
528 * @param a An argument to the curried function.
529 * @param b An argument to the curried function.
530 * @param c An argument to the curried function.
531 * @return A curried form of the given function.
532 */
533 public static <A, B, C, D, E, F$> F<D, F<E, F$>> curry(final F5<A, B, C, D, E, F$> f, final A a, final B b,
534 final C c) {
535 return curry(f).f(a).f(b).f(c);
536 }
537
538 /**
539 * Curry a function of arity-5.
540 *
541 * @param f The function to curry.
542 * @param a An argument to the curried function.
543 * @param b An argument to the curried function.
544 * @param c An argument to the curried function.
545 * @param d An argument to the curried function.
546 * @return A curried form of the given function.
547 */
548 public static <A, B, C, D, E, F$> F<E, F$> curry(final F5<A, B, C, D, E, F$> f, final A a, final B b, final C c,
549 final D d) {
550 return curry(f).f(a).f(b).f(c).f(d);
551 }
552
553 /**
554 * Uncurry a function of arity-5.
555 *
556 * @return An uncurried function.
557 */
558 public static <A, B, C, D, E, F$> F<F<A, F<B, F<C, F<D, F<E, F$>>>>>, F5<A, B, C, D, E, F$>> uncurryF5() {
559 return new F<F<A, F<B, F<C, F<D, F<E, F$>>>>>, F5<A, B, C, D, E, F$>>() {
560 public F5<A, B, C, D, E, F$> f(final F<A, F<B, F<C, F<D, F<E, F$>>>>> f) {
561 return uncurryF5(f);
562 }
563 };
564 }
565
566 /**
567 * Uncurry a function of arity-6.
568 *
569 * @param f The function to uncurry.
570 * @return An uncurried function.
571 */
572 public static <A, B, C, D, E, F$> F5<A, B, C, D, E, F$> uncurryF5(final F<A, F<B, F<C, F<D, F<E, F$>>>>> f) {
573 return new F5<A, B, C, D, E, F$>() {
574 public F$ f(final A a, final B b, final C c, final D d, final E e) {
575 return f.f(a).f(b).f(c).f(d).f(e);
576 }
577 };
578 }
579
580 /**
581 * Curry a function of arity-6.
582 *
583 * @param f The function to curry.
584 * @return A curried form of the given function.
585 */
586 public static <A, B, C, D, E, F$, G> F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>> curry(final F6<A, B, C, D, E, F$, G> f) {
587 return new F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>>() {
588 public F<B, F<C, F<D, F<E, F<F$, G>>>>> f(final A a) {
589 return new F<B, F<C, F<D, F<E, F<F$, G>>>>>() {
590 public F<C, F<D, F<E, F<F$, G>>>> f(final B b) {
591 return new F<C, F<D, F<E, F<F$, G>>>>() {
592 public F<D, F<E, F<F$, G>>> f(final C c) {
593 return new F<D, F<E, F<F$, G>>>() {
594 public F<E, F<F$, G>> f(final D d) {
595 return new F<E, F<F$, G>>() {
596 public F<F$, G> f(final E e) {
597 return new F<F$, G>() {
598 public G f(final F$ f$) {
599 return f.f(a, b, c, d, e, f$);
600 }
601 };
602 }
603 };
604 }
605 };
606 }
607 };
608 }
609 };
610 }
611 };
612 }
613
614 /**
615 * Uncurry a function of arity-6.
616 *
617 * @return An uncurried function.
618 */
619 public static <A, B, C, D, E, F$, G> F<F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>>, F6<A, B, C, D, E, F$, G>> uncurryF6() {
620 return new F<F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>>, F6<A, B, C, D, E, F$, G>>() {
621 public F6<A, B, C, D, E, F$, G> f(final F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>> f) {
622 return uncurryF6(f);
623 }
624 };
625 }
626
627 /**
628 * Uncurry a function of arity-6.
629 *
630 * @param f The function to uncurry.
631 * @return An uncurried function.
632 */
633 public static <A, B, C, D, E, F$, G> F6<A, B, C, D, E, F$, G> uncurryF6(
634 final F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>> f) {
635 return new F6<A, B, C, D, E, F$, G>() {
636 public G f(final A a, final B b, final C c, final D d, final E e, final F$ f$) {
637 return f.f(a).f(b).f(c).f(d).f(e).f(f$);
638 }
639 };
640 }
641
642 /**
643 * Curry a function of arity-7.
644 *
645 * @param f The function to curry.
646 * @return A curried form of the given function.
647 */
648 public static <A, B, C, D, E, F$, G, H> F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>> curry(
649 final F7<A, B, C, D, E, F$, G, H> f) {
650 return new F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>>() {
651 public F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>> f(final A a) {
652 return new F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>() {
653 public F<C, F<D, F<E, F<F$, F<G, H>>>>> f(final B b) {
654 return new F<C, F<D, F<E, F<F$, F<G, H>>>>>() {
655 public F<D, F<E, F<F$, F<G, H>>>> f(final C c) {
656 return new F<D, F<E, F<F$, F<G, H>>>>() {
657 public F<E, F<F$, F<G, H>>> f(final D d) {
658 return new F<E, F<F$, F<G, H>>>() {
659 public F<F$, F<G, H>> f(final E e) {
660 return new F<F$, F<G, H>>() {
661 public F<G, H> f(final F$ f$) {
662 return new F<G, H>() {
663 public H f(final G g) {
664 return f.f(a, b, c, d, e, f$, g);
665 }
666 };
667 }
668 };
669 }
670 };
671 }
672 };
673 }
674 };
675 }
676 };
677 }
678 };
679 }
680
681 /**
682 * Curry a function of arity-7.
683 *
684 * @param f The function to curry.
685 * @param a An argument to the curried function.
686 * @return A curried form of the given function.
687 */
688 public static <A, B, C, D, E, F$, G, H> F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>> curry(
689 final F7<A, B, C, D, E, F$, G, H> f, final A a) {
690 return curry(f).f(a);
691 }
692
693 /**
694 * Curry a function of arity-7.
695 *
696 * @param f The function to curry.
697 * @param a An argument to the curried function.
698 * @param b An argument to the curried function.
699 * @return A curried form of the given function.
700 */
701 public static <A, B, C, D, E, F$, G, H> F<C, F<D, F<E, F<F$, F<G, H>>>>> curry(final F7<A, B, C, D, E, F$, G, H> f,
702 final A a, final B b) {
703 return curry(f).f(a).f(b);
704 }
705
706 /**
707 * Curry a function of arity-7.
708 *
709 * @param f The function to curry.
710 * @param a An argument to the curried function.
711 * @param b An argument to the curried function.
712 * @param c An argument to the curried function.
713 * @return A curried form of the given function.
714 */
715 public static <A, B, C, D, E, F$, G, H> F<D, F<E, F<F$, F<G, H>>>> curry(final F7<A, B, C, D, E, F$, G, H> f,
716 final A a, final B b, final C c) {
717 return curry(f).f(a).f(b).f(c);
718 }
719
720 /**
721 * Curry a function of arity-7.
722 *
723 * @param f The function to curry.
724 * @param a An argument to the curried function.
725 * @param b An argument to the curried function.
726 * @param c An argument to the curried function.
727 * @param d An argument to the curried function.
728 * @return A curried form of the given function.
729 */
730 public static <A, B, C, D, E, F$, G, H> F<E, F<F$, F<G, H>>> curry(final F7<A, B, C, D, E, F$, G, H> f, final A a,
731 final B b, final C c, final D d) {
732 return curry(f).f(a).f(b).f(c).f(d);
733 }
734
735 /**
736 * Curry a function of arity-7.
737 *
738 * @param f The function to curry.
739 * @param a An argument to the curried function.
740 * @param b An argument to the curried function.
741 * @param c An argument to the curried function.
742 * @param d An argument to the curried function.
743 * @param e An argument to the curried function.
744 * @return A curried form of the given function.
745 */
746 public static <A, B, C, D, E, F$, G, H> F<F$, F<G, H>> curry(final F7<A, B, C, D, E, F$, G, H> f, final A a,
747 final B b, final C c, final D d, final E e) {
748 return curry(f).f(a).f(b).f(c).f(d).f(e);
749 }
750
751 /**
752 * Curry a function of arity-7.
753 *
754 * @param f The function to curry.
755 * @param a An argument to the curried function.
756 * @param b An argument to the curried function.
757 * @param c An argument to the curried function.
758 * @param d An argument to the curried function.
759 * @param e An argument to the curried function.
760 * @param f$ An argument to the curried function.
761 * @return A curried form of the given function.
762 */
763 public static <A, B, C, D, E, F$, G, H> F<G, H> curry(final F7<A, B, C, D, E, F$, G, H> f, final A a, final B b,
764 final C c, final D d, final E e, final F$ f$) {
765 return curry(f).f(a).f(b).f(c).f(d).f(e).f(f$);
766 }
767
768 /**
769 * Uncurry a function of arity-7.
770 *
771 * @return An uncurried function.
772 */
773 public static <A, B, C, D, E, F$, G, H> F<F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>>, F7<A, B, C, D, E, F$, G, H>> uncurryF7() {
774 return new F<F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>>, F7<A, B, C, D, E, F$, G, H>>() {
775 public F7<A, B, C, D, E, F$, G, H> f(final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>> f) {
776 return uncurryF7(f);
777 }
778 };
779 }
780
781 /**
782 * Uncurry a function of arity-7.
783 *
784 * @param f The function to uncurry.
785 * @return An uncurried function.
786 */
787 public static <A, B, C, D, E, F$, G, H> F7<A, B, C, D, E, F$, G, H> uncurryF7(
788 final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>> f) {
789 return new F7<A, B, C, D, E, F$, G, H>() {
790 public H f(final A a, final B b, final C c, final D d, final E e, final F$ f$, final G g) {
791 return f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g);
792 }
793 };
794 }
795
796 /**
797 * Curry a function of arity-8.
798 *
799 * @param f The function to curry.
800 * @return A curried form of the given function.
801 */
802 public static <A, B, C, D, E, F$, G, H, I> F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>> curry(
803 final F8<A, B, C, D, E, F$, G, H, I> f) {
804 return new F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>>() {
805 public F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>> f(final A a) {
806 return new F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>() {
807 public F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>> f(final B b) {
808 return new F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>() {
809 public F<D, F<E, F<F$, F<G, F<H, I>>>>> f(final C c) {
810 return new F<D, F<E, F<F$, F<G, F<H, I>>>>>() {
811 public F<E, F<F$, F<G, F<H, I>>>> f(final D d) {
812 return new F<E, F<F$, F<G, F<H, I>>>>() {
813 public F<F$, F<G, F<H, I>>> f(final E e) {
814 return new F<F$, F<G, F<H, I>>>() {
815 public F<G, F<H, I>> f(final F$ f$) {
816 return new F<G, F<H, I>>() {
817 public F<H, I> f(final G g) {
818 return new F<H, I>() {
819 public I f(final H h) {
820 return f.f(a, b, c, d, e, f$, g, h);
821 }
822 };
823 }
824 };
825 }
826 };
827 }
828 };
829 }
830 };
831 }
832 };
833 }
834 };
835 }
836 };
837 }
838
839 /**
840 * Curry a function of arity-8.
841 *
842 * @param f The function to curry.
843 * @param a An argument to the curried function.
844 * @return A curried form of the given function.
845 */
846 public static <A, B, C, D, E, F$, G, H, I> F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>> curry(
847 final F8<A, B, C, D, E, F$, G, H, I> f, final A a) {
848 return curry(f).f(a);
849 }
850
851 /**
852 * Curry a function of arity-8.
853 *
854 * @param f The function to curry.
855 * @param a An argument to the curried function.
856 * @param b An argument to the curried function.
857 * @return A curried form of the given function.
858 */
859 public static <A, B, C, D, E, F$, G, H, I> F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>> curry(
860 final F8<A, B, C, D, E, F$, G, H, I> f, final A a, final B b) {
861 return curry(f).f(a).f(b);
862 }
863
864 /**
865 * Curry a function of arity-8.
866 *
867 * @param f The function to curry.
868 * @param a An argument to the curried function.
869 * @param b An argument to the curried function.
870 * @param c An argument to the curried function.
871 * @return A curried form of the given function.
872 */
873 public static <A, B, C, D, E, F$, G, H, I> F<D, F<E, F<F$, F<G, F<H, I>>>>> curry(
874 final F8<A, B, C, D, E, F$, G, H, I> f, final A a, final B b, final C c) {
875 return curry(f).f(a).f(b).f(c);
876 }
877
878 /**
879 * Curry a function of arity-8.
880 *
881 * @param f The function to curry.
882 * @param a An argument to the curried function.
883 * @param b An argument to the curried function.
884 * @param c An argument to the curried function.
885 * @param d An argument to the curried function.
886 * @return A curried form of the given function.
887 */
888 public static <A, B, C, D, E, F$, G, H, I> F<E, F<F$, F<G, F<H, I>>>> curry(final F8<A, B, C, D, E, F$, G, H, I> f,
889 final A a, final B b, final C c,
890 final D d) {
891 return curry(f).f(a).f(b).f(c).f(d);
892 }
893
894 /**
895 * Curry a function of arity-8.
896 *
897 * @param f The function to curry.
898 * @param a An argument to the curried function.
899 * @param b An argument to the curried function.
900 * @param c An argument to the curried function.
901 * @param d An argument to the curried function.
902 * @param e An argument to the curried function.
903 * @return A curried form of the given function.
904 */
905 public static <A, B, C, D, E, F$, G, H, I> F<F$, F<G, F<H, I>>> curry(final F8<A, B, C, D, E, F$, G, H, I> f,
906 final A a, final B b, final C c, final D d,
907 final E e) {
908 return curry(f).f(a).f(b).f(c).f(d).f(e);
909 }
910
911 /**
912 * Curry a function of arity-8.
913 *
914 * @param f The function to curry.
915 * @param a An argument to the curried function.
916 * @param b An argument to the curried function.
917 * @param c An argument to the curried function.
918 * @param d An argument to the curried function.
919 * @param e An argument to the curried function.
920 * @param f$ An argument to the curried function.
921 * @return A curried form of the given function.
922 */
923 public static <A, B, C, D, E, F$, G, H, I> F<G, F<H, I>> curry(final F8<A, B, C, D, E, F$, G, H, I> f, final A a,
924 final B b, final C c, final D d, final E e,
925 final F$ f$) {
926 return curry(f).f(a).f(b).f(c).f(d).f(e).f(f$);
927 }
928
929 /**
930 * Curry a function of arity-7.
931 *
932 * @param f The function to curry.
933 * @param a An argument to the curried function.
934 * @param b An argument to the curried function.
935 * @param c An argument to the curried function.
936 * @param d An argument to the curried function.
937 * @param e An argument to the curried function.
938 * @param f$ An argument to the curried function.
939 * @param g An argument to the curried function.
940 * @return A curried form of the given function.
941 */
942 public static <A, B, C, D, E, F$, G, H, I> F<H, I> curry(final F8<A, B, C, D, E, F$, G, H, I> f, final A a, final B b,
943 final C c, final D d, final E e, final F$ f$, final G g) {
944 return curry(f).f(a).f(b).f(c).f(d).f(e).f(f$).f(g);
945 }
946
947 /**
948 * Uncurry a function of arity-8.
949 *
950 * @return An uncurried function.
951 */
952 public static <A, B, C, D, E, F$, G, H, I> F<F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>>, F8<A, B, C, D, E, F$, G, H, I>> uncurryF8() {
953 return new F<F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>>, F8<A, B, C, D, E, F$, G, H, I>>() {
954 public F8<A, B, C, D, E, F$, G, H, I> f(final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>> f) {
955 return uncurryF8(f);
956 }
957 };
958 }
959
960 /**
961 * Uncurry a function of arity-8.
962 *
963 * @param f The function to uncurry.
964 * @return An uncurried function.
965 */
966 public static <A, B, C, D, E, F$, G, H, I> F8<A, B, C, D, E, F$, G, H, I> uncurryF8(
967 final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>> f) {
968 return new F8<A, B, C, D, E, F$, G, H, I>() {
969 public I f(final A a, final B b, final C c, final D d, final E e, final F$ f$, final G g, final H h) {
970 return f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g).f(h);
971 }
972 };
973 }
974
975 /**
976 * Binds the function in the second argument to the function in the first argument.
977 *
978 * @param ma A function whose argument type is the same as the argument type of the return value.
979 * @param f A function whose argument type is the same as the return type of <em>ma</em>,
980 * and yields the return value.
981 * @return A function that chains the given functions together such that the result of applying
982 * <em>ma</em> to the argument is given to <i>f</i>, yielding a function
983 * that is applied to the argument again.
984 */
985 public static <A, B, C> F<C, B> bind(final F<C, A> ma, final F<A, F<C, B>> f) {
986 return new F<C, B>() {
987 public B f(final C m) {
988 return f.f(ma.f(m)).f(m);
989 }
990 };
991 }
992
993 /**
994 * Performs function application within a higher-order function (applicative functor pattern).
995 *
996 * @param cab The higher-order function to apply a function to.
997 * @param ca A function to apply within a higher-order function.
998 * @return A new function after applying the given higher-order function to the given function.
999 */
1000 public static <A, B, C> F<C, B> apply(final F<C, F<A, B>> cab, final F<C, A> ca) {
1001 return bind(cab, new F<F<A, B>, F<C, B>>() {
1002 public F<C, B> f(final F<A, B> f) {
1003 return compose(new F<A, B>() {
1004 public B f(final A a) {
1005 return f.f(a);
1006 }
1007 }, ca);
1008 }
1009 });
1010 }
1011
1012 /**
1013 * Binds the given function <em>f</em> to the values of the given functions, with a final join.
1014 *
1015 * @param ca A function to bind <em>f</em> function to.
1016 * @param cb A function to bind <em>f</em> function to.
1017 * @param f The bound function to be composed with <em>ca</em> and then applied with <em>cb</em>
1018 * @return A new function after performing the composition, then application.
1019 */
1020 public static <A, B, C, D> F<D, C> bind(final F<D, A> ca, final F<D, B> cb, final F<A, F<B, C>> f) {
1021 return apply(compose(f, ca), cb);
1022 }
1023
1024 /**
1025 * Applies a given function over the arguments of another function of arity-2.
1026 *
1027 * @param a The function whose arguments to apply another function over.
1028 * @param f The function to apply over the arguments of another function.
1029 * @return A function whose arguments are fed through function f, before being passed to function a.
1030 */
1031 public static <A, B, C> F<B, F<B, C>> on(final F<A, F<A, C>> a, final F<B, A> f) {
1032 return compose(compose(Function.<B, A, C>andThen().f(f), a), f);
1033 }
1034
1035 /**
1036 * Promotes a function of arity-2 to a higher-order function.
1037 *
1038 * @param f The function to promote.
1039 * @return A function of arity-2 promoted to compose with two functions.
1040 */
1041 public static <A, B, C, D> F<F<D, A>, F<F<D, B>, F<D, C>>> lift(final F<A, F<B, C>> f) {
1042 return curry(new F2<F<D, A>, F<D, B>, F<D, C>>() {
1043 public F<D, C> f(final F<D, A> ca, final F<D, B> cb) {
1044 return bind(ca, cb, f);
1045 }
1046 });
1047 }
1048
1049 /**
1050 * Joins two arguments of a function of arity-2 into one argument, yielding a function of arity-1.
1051 *
1052 * @param f A function whose arguments to join.
1053 * @return A function of arity-1 whose argument is substituted for both parameters of <em>f</em>.
1054 */
1055 public static <A, B> F<B, A> join(final F<B, F<B, A>> f) {
1056 return bind(f, Function.<F<B, A>>identity());
1057 }
1058
1059
1060 /**
1061 * Partial application of the second argument to the supplied function to get a function of type
1062 * <tt>A -> C</tt>. Same as <tt>flip(f).f(b)</tt>.
1063 *
1064 * @param f The function to partially apply.
1065 * @param b The value to apply to the function.
1066 * @return A new function based on <tt>f</tt> with its second argument applied.
1067 */
1068 public static <A, B, C> F<A, C> partialApply2(final F<A, F<B, C>> f, final B b) {
1069 return new F<A, C>() {
1070 public C f(final A a) {
1071 return uncurryF2(f).f(a, b);
1072 }
1073 };
1074 }
1075
1076 /**
1077 * Partial application of the third argument to the supplied function to get a function of type
1078 * <tt>A -> B -> D</tt>.
1079 *
1080 * @param f The function to partially apply.
1081 * @param c The value to apply to the function.
1082 * @return A new function based on <tt>f</tt> with its third argument applied.
1083 */
1084 public static <A, B, C, D> F<A, F<B, D>> partialApply3(final F<A, F<B, F<C, D>>> f, final C c) {
1085 return new F<A, F<B, D>>() {
1086 public F<B, D> f(final A a) {
1087 return new F<B, D>() {
1088 public D f(final B b) {
1089 return uncurryF3(f).f(a, b, c);
1090 }
1091 };
1092 }
1093 };
1094 }
1095
1096 /**
1097 * Partial application of the fourth argument to the supplied function to get a function of type
1098 * <tt>A -> B -> C -> E</tt>.
1099 *
1100 * @param f The function to partially apply.
1101 * @param d The value to apply to the function.
1102 * @return A new function based on <tt>f</tt> with its fourth argument applied.
1103 */
1104 public static <A, B, C, D, E> F<A, F<B, F<C, E>>> partialApply4(final F<A, F<B, F<C, F<D, E>>>> f, final D d) {
1105 return new F<A, F<B, F<C, E>>>() {
1106 public F<B, F<C, E>> f(final A a) {
1107 return new F<B, F<C, E>>() {
1108 public F<C, E> f(final B b) {
1109 return new F<C, E>() {
1110 public E f(final C c) {
1111 return uncurryF4(f).f(a, b, c, d);
1112 }
1113 };
1114 }
1115 };
1116 }
1117 };
1118 }
1119
1120 /**
1121 * Partial application of the fifth argument to the supplied function to get a function of type
1122 * <tt>A -> B -> C -> D -> F$</tt>.
1123 *
1124 * @param f The function to partially apply.
1125 * @param e The value to apply to the function.
1126 * @return A new function based on <tt>f</tt> with its fifth argument applied.
1127 */
1128 public static <A, B, C, D, E, F$> F<A, F<B, F<C, F<D, F$>>>> partialApply5(final F<A, F<B, F<C, F<D, F<E, F$>>>>> f,
1129 final E e) {
1130 return new F<A, F<B, F<C, F<D, F$>>>>() {
1131 public F<B, F<C, F<D, F$>>> f(final A a) {
1132 return new F<B, F<C, F<D, F$>>>() {
1133 public F<C, F<D, F$>> f(final B b) {
1134 return new F<C, F<D, F$>>() {
1135 public F<D, F$> f(final C c) {
1136 return new F<D, F$>() {
1137 public F$ f(final D d) {
1138 return uncurryF5(f).f(a, b, c, d, e);
1139 }
1140 };
1141 }
1142 };
1143 }
1144 };
1145 }
1146 };
1147 }
1148
1149 /**
1150 * Partial application of the sixth argument to the supplied function to get a function of type
1151 * <tt>A -> B -> C -> D -> E -> G</tt>.
1152 *
1153 * @param f The function to partially apply.
1154 * @param f$ The value to apply to the function.
1155 * @return A new function based on <tt>f</tt> with its sixth argument applied.
1156 */
1157 public static <A, B, C, D, E, F$, G> F<A, F<B, F<C, F<D, F<E, G>>>>> partialApply6(
1158 final F<A, F<B, F<C, F<D, F<E, F<F$, G>>>>>> f, final F$ f$) {
1159 return new F<A, F<B, F<C, F<D, F<E, G>>>>>() {
1160 public F<B, F<C, F<D, F<E, G>>>> f(final A a) {
1161 return new F<B, F<C, F<D, F<E, G>>>>() {
1162 public F<C, F<D, F<E, G>>> f(final B b) {
1163 return new F<C, F<D, F<E, G>>>() {
1164 public F<D, F<E, G>> f(final C c) {
1165 return new F<D, F<E, G>>() {
1166 public F<E, G> f(final D d) {
1167 return new F<E, G>() {
1168 public G f(final E e) {
1169 return uncurryF6(f).f(a, b, c, d, e, f$);
1170 }
1171 };
1172 }
1173 };
1174 }
1175 };
1176 }
1177 };
1178 }
1179 };
1180 }
1181
1182 /**
1183 * Partial application of the seventh argument to the supplied function to get a function of type
1184 * <tt>A -> B -> C -> D -> E -> F$ -> H</tt>.
1185 *
1186 * @param f The function to partially apply.
1187 * @param g The value to apply to the function.
1188 * @return A new function based on <tt>f</tt> with its seventh argument applied.
1189 */
1190 public static <A, B, C, D, E, F$, G, H> F<A, F<B, F<C, F<D, F<E, F<F$, H>>>>>> partialApply7(
1191 final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, H>>>>>>> f, final G g) {
1192 return new F<A, F<B, F<C, F<D, F<E, F<F$, H>>>>>>() {
1193 public F<B, F<C, F<D, F<E, F<F$, H>>>>> f(final A a) {
1194 return new F<B, F<C, F<D, F<E, F<F$, H>>>>>() {
1195 public F<C, F<D, F<E, F<F$, H>>>> f(final B b) {
1196 return new F<C, F<D, F<E, F<F$, H>>>>() {
1197 public F<D, F<E, F<F$, H>>> f(final C c) {
1198 return new F<D, F<E, F<F$, H>>>() {
1199 public F<E, F<F$, H>> f(final D d) {
1200 return new F<E, F<F$, H>>() {
1201 public F<F$, H> f(final E e) {
1202 return new F<F$, H>() {
1203 public H f(final F$ f$) {
1204 return uncurryF7(f).f(a, b, c, d, e, f$, g);
1205 }
1206 };
1207 }
1208 };
1209 }
1210 };
1211 }
1212 };
1213 }
1214 };
1215 }
1216 };
1217 }
1218
1219 /**
1220 * Partial application of the eigth argument to the supplied function to get a function of type
1221 * <tt>A -> B -> C -> D -> E -> F$ -> G -> I</tt>.
1222 *
1223 * @param f The function to partially apply.
1224 * @param h The value to apply to the function.
1225 * @return A new function based on <tt>f</tt> with its eigth argument applied.
1226 */
1227 public static <A, B, C, D, E, F$, G, H, I> F<A, F<B, F<C, F<D, F<E, F<F$, F<G, I>>>>>>> partialApply8(
1228 final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, I>>>>>>>> f, final H h) {
1229 return new F<A, F<B, F<C, F<D, F<E, F<F$, F<G, I>>>>>>>() {
1230 public F<B, F<C, F<D, F<E, F<F$, F<G, I>>>>>> f(final A a) {
1231 return new F<B, F<C, F<D, F<E, F<F$, F<G, I>>>>>>() {
1232 public F<C, F<D, F<E, F<F$, F<G, I>>>>> f(final B b) {
1233 return new F<C, F<D, F<E, F<F$, F<G, I>>>>>() {
1234 public F<D, F<E, F<F$, F<G, I>>>> f(final C c) {
1235 return new F<D, F<E, F<F$, F<G, I>>>>() {
1236 public F<E, F<F$, F<G, I>>> f(final D d) {
1237 return new F<E, F<F$, F<G, I>>>() {
1238 public F<F$, F<G, I>> f(final E e) {
1239 return new F<F$, F<G, I>>() {
1240 public F<G, I> f(final F$ f$) {
1241 return new F<G, I>() {
1242 public I f(final G g) {
1243 return uncurryF8(f).f(a, b, c, d, e, f$, g, h);
1244 }
1245 };
1246 }
1247 };
1248 }
1249 };
1250 }
1251 };
1252 }
1253 };
1254 }
1255 };
1256 }
1257 };
1258 }
1259 }