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