001 package fj; 002 003 /** 004 * Transformations on functions. 005 * 006 * @version %build.number%<br> 007 * <ul> 008 * <li>$LastChangedRevision: 173 $</li> 009 * <li>$LastChangedDate: 2009-06-19 16:01:56 +1000 (Fri, 19 Jun 2009) $</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 }