fj.Function Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionaljava Show documentation
Show all versions of functionaljava Show documentation
Functional Java is an open source library that supports closures for the Java programming language
package fj;
import fj.data.Option;
/**
* Transformations on functions.
*
* @version %build.number%
*/
public final class Function {
private Function() {
throw new UnsupportedOperationException();
}
/**
* Function application with the arguments flipped.
*
* @param a The value to apply the function to.
* @return A function that is partially-applied to the given value.
*/
public static F, B> apply(final A a) {
return f -> f.f(a);
}
/**
* Function composition.
*
* @return A function that composes two functions to produce a new function.
*/
public static F, F, F>> compose() {
return f -> g -> compose(f, g);
}
/**
* Function composition.
*
* @param f A function to compose with another.
* @param g A function to compose with another.
* @return A function that is the composition of the given arguments.
*/
public static F compose(final F f, final F g) {
return a -> f.f(g.f(a));
}
/**
* Function composition.
*
* @param f A function to compose with another.
* @param g A function to compose with another.
* @return A function that is the composition of the given arguments.
*/
public static F> compose2(final F f, final F> g) {
return a -> b -> f.f(g.f(a).f(b));
}
/**
* Function composition flipped.
*
* @return A function that composes two functions to produce a new function.
*/
public static F, F, F>> andThen() {
return g -> f -> andThen(g, f);
}
/**
* Function composition flipped.
*
* @param g A function to compose with another.
* @param f A function to compose with another.
* @return A function that is the composition of the given arguments.
*/
public static F andThen(final F g, final F f) {
return a -> f.f(g.f(a));
}
/**
* The identity transformation.
*
* @return The identity transformation.
*/
public static F identity() {
return a -> a;
}
/**
* Returns a function that given an argument, returns a function that ignores its argument.
*
* @return A function that given an argument, returns a function that ignores its argument.
*/
public static F> constant() {
return Function::constant;
}
/**
* Returns a function that ignores its argument to constantly produce the given value.
*
* @param b The value to return when the returned function is applied.
* @return A function that ignores its argument to constantly produce the given value.
*/
public static F constant(final B b) {
return a -> b;
}
/**
* Simultaneously covaries and contravaries a function.
*
* @param f The function to vary.
* @return A co- and contravariant function that invokes f on its argument.
*/
public static F vary(final F super A, ? extends B> f) {
return f::f;
}
/**
* Simultaneously covaries and contravaries a function.
*
* @return A function that varies and covaries a function.
*/
public static F, F> vary() {
return Function::vary;
}
/**
* Function argument flipping.
*
* @return A function that takes a function and flips its arguments.
*/
public static F>, F>> flip() {
return Function::flip;
}
/**
* Function argument flipping.
*
* @param f The function to flip.
* @return The given function flipped.
*/
public static F> flip(final F> f) {
return b -> a -> f.f(a).f(b);
}
/**
* Function argument flipping.
*
* @param f The function to flip.
* @return The given function flipped.
*/
public static F2 flip(final F2 f) {
return (b, a) -> f.f(a, b);
}
/**
* Function argument flipping.
*
* @return A function that flips the arguments of a given function.
*/
public static F, F2> flip2() {
return Function::flip;
}
/**
* Return a function that inspects the argument of the given function for a null
value and if so, does
* not apply the value, instead returning an empty optional value.
*
* @param f The function to check for a null
argument.
* @return A function that inspects the argument of the given function for a null
value and if so, does
* not apply the value, instead returning an empty optional value.
*/
public static F> nullable(final F f) {
return a -> a == null ? Option.none() : Option.some(f.f(a));
}
/**
* Curry a function of arity-2.
*
* @param f The function to curry.
* @return A curried form of the given function.
*/
public static F> curry(final F2 f) {
return a -> b -> f.f(a, b);
}
/**
* Curry a function of arity-2.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @return A curried form of the given function.
*/
public static F curry(final F2 f, final A a) {
return curry(f).f(a);
}
/**
* Uncurry a function of arity-2.
*
* @return An uncurried function.
*/
public static F>, F2> uncurryF2() {
return Function::uncurryF2;
}
/**
* Uncurry a function of arity-2.
*
* @param f The function to uncurry.
* @return An uncurried function.
*/
public static F2 uncurryF2(final F> f) {
return (a, b) -> f.f(a).f(b);
}
/**
* Curry a function of arity-3.
*
* @param f The function to curry.
* @return A curried form of the given function.
*/
public static F>> curry(final F3 f) {
return a -> b -> c -> f.f(a, b, c);
}
/**
* Curry a function of arity-3.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @return A curried form of the given function.
*/
public static F> curry(final F3 f, final A a) {
return curry(f).f(a);
}
/**
* Curry a function of arity-3.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @return A curried form of the given function.
*/
public static F curry(final F3 f, final A a, final B b) {
return curry(f, a).f(b);
}
/**
* Uncurry a function of arity-3.
*
* @return An uncurried function.
*/
public static F>>, F3> uncurryF3() {
return Function::uncurryF3;
}
/**
* Uncurry a function of arity-3.
*
* @param f The function to uncurry.
* @return An uncurried function.
*/
public static F3 uncurryF3(final F>> f) {
return (a, b, c) -> f.f(a).f(b).f(c);
}
/**
* Curry a function of arity-4.
*
* @param f The function to curry.
* @return A curried form of the given function.
*/
public static F>>> curry(final F4 f) {
return a -> b -> c -> d -> f.f(a, b, c, d);
}
/**
* Curry a function of arity-4.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>> curry(final F4 f, final A a) {
return curry(f).f(a);
}
/**
* Curry a function of arity-4.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @return A curried form of the given function.
*/
public static F> curry(final F4 f, final A a, final B b) {
return curry(f).f(a).f(b);
}
/**
* Curry a function of arity-4.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @return A curried form of the given function.
*/
public static F curry(final F4 f, final A a, final B b, final C c) {
return curry(f).f(a).f(b).f(c);
}
/**
* Uncurry a function of arity-4.
*
* @return An uncurried function.
*/
public static F>>>, F4> uncurryF4() {
return Function::uncurryF4;
}
/**
* Uncurry a function of arity-4.
*
* @param f The function to uncurry.
* @return An uncurried function.
*/
public static F4 uncurryF4(final F>>> f) {
return (a, b, c, d) -> f.f(a).f(b).f(c).f(d);
}
/**
* Curry a function of arity-5.
*
* @param f The function to curry.
* @return A curried form of the given function.
*/
public static F>>>> curry(final F5 f) {
return a -> b -> c -> d -> e -> f.f(a, b, c, d, e);
}
/**
* Curry a function of arity-5.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>> curry(final F5 f, final A a) {
return curry(f).f(a);
}
/**
* Curry a function of arity-5.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>> curry(final F5 f, final A a, final B b) {
return curry(f).f(a).f(b);
}
/**
* Curry a function of arity-5.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @return A curried form of the given function.
*/
public static F> curry(final F5 f, final A a, final B b,
final C c) {
return curry(f).f(a).f(b).f(c);
}
/**
* Curry a function of arity-5.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @return A curried form of the given function.
*/
public static F curry(final F5 f, final A a, final B b, final C c,
final D d) {
return curry(f).f(a).f(b).f(c).f(d);
}
/**
* Uncurry a function of arity-5.
*
* @return An uncurried function.
*/
public static F>>>>, F5> uncurryF5() {
return Function::uncurryF5;
}
/**
* Uncurry a function of arity-6.
*
* @param f The function to uncurry.
* @return An uncurried function.
*/
public static F5 uncurryF5(final F>>>> f) {
return (a, b, c, d, e) -> f.f(a).f(b).f(c).f(d).f(e);
}
/**
* Curry a function of arity-6.
*
* @param f The function to curry.
* @return A curried form of the given function.
*/
public static F>>>>> curry(final F6 f) {
return a -> b -> c -> d -> e -> f$ -> f.f(a, b, c, d, e, f$);
}
/**
* Uncurry a function of arity-6.
*
* @return An uncurried function.
*/
public static F>>>>>, F6> uncurryF6() {
return Function::uncurryF6;
}
/**
* Uncurry a function of arity-6.
*
* @param f The function to uncurry.
* @return An uncurried function.
*/
public static F6 uncurryF6(
final F>>>>> f) {
return (a, b, c, d, e, f$) -> f.f(a).f(b).f(c).f(d).f(e).f(f$);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @return A curried form of the given function.
*/
public static F>>>>>> curry(
final F7 f) {
return a -> b -> c -> d -> e -> f$ -> g -> f.f(a, b, c, d, e, f$, g);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>>>> curry(
final F7 f, final A a) {
return curry(f).f(a);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>>> curry(final F7 f,
final A a, final B b) {
return curry(f).f(a).f(b);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>> curry(final F7 f,
final A a, final B b, final C c) {
return curry(f).f(a).f(b).f(c);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>> curry(final F7 f, final A a,
final B b, final C c, final D d) {
return curry(f).f(a).f(b).f(c).f(d);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @param e An argument to the curried function.
* @return A curried form of the given function.
*/
public static F> curry(final F7 f, final A a,
final B b, final C c, final D d, final E e) {
return curry(f).f(a).f(b).f(c).f(d).f(e);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @param e An argument to the curried function.
* @param f$ An argument to the curried function.
* @return A curried form of the given function.
*/
public static F curry(final F7 f, final A a, final B b,
final C c, final D d, final E e, final F$ f$) {
return curry(f).f(a).f(b).f(c).f(d).f(e).f(f$);
}
/**
* Uncurry a function of arity-7.
*
* @return An uncurried function.
*/
public static F>>>>>>, F7> uncurryF7() {
return Function::uncurryF7;
}
/**
* Uncurry a function of arity-7.
*
* @param f The function to uncurry.
* @return An uncurried function.
*/
public static F7 uncurryF7(
final F>>>>>> f) {
return (a, b, c, d, e, f$, g) -> f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g);
}
/**
* Curry a function of arity-8.
*
* @param f The function to curry.
* @return A curried form of the given function.
*/
public static F>>>>>>> curry(
final F8 f) {
return a -> b -> c -> d -> e -> f$ -> g -> h -> f.f(a, b, c, d, e, f$, g, h);
}
/**
* Curry a function of arity-8.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>>>>> curry(
final F8 f, final A a) {
return curry(f).f(a);
}
/**
* Curry a function of arity-8.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>>>> curry(
final F8 f, final A a, final B b) {
return curry(f).f(a).f(b);
}
/**
* Curry a function of arity-8.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>>> curry(
final F8 f, final A a, final B b, final C c) {
return curry(f).f(a).f(b).f(c);
}
/**
* Curry a function of arity-8.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>>> curry(final F8 f,
final A a, final B b, final C c,
final D d) {
return curry(f).f(a).f(b).f(c).f(d);
}
/**
* Curry a function of arity-8.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @param e An argument to the curried function.
* @return A curried form of the given function.
*/
public static F>> curry(final F8 f,
final A a, final B b, final C c, final D d,
final E e) {
return curry(f).f(a).f(b).f(c).f(d).f(e);
}
/**
* Curry a function of arity-8.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @param e An argument to the curried function.
* @param f$ An argument to the curried function.
* @return A curried form of the given function.
*/
public static F> curry(final F8 f, final A a,
final B b, final C c, final D d, final E e,
final F$ f$) {
return curry(f).f(a).f(b).f(c).f(d).f(e).f(f$);
}
/**
* Curry a function of arity-7.
*
* @param f The function to curry.
* @param a An argument to the curried function.
* @param b An argument to the curried function.
* @param c An argument to the curried function.
* @param d An argument to the curried function.
* @param e An argument to the curried function.
* @param f$ An argument to the curried function.
* @param g An argument to the curried function.
* @return A curried form of the given function.
*/
public static F curry(final F8 f, final A a, final B b,
final C c, final D d, final E e, final F$ f$, final G g) {
return curry(f).f(a).f(b).f(c).f(d).f(e).f(f$).f(g);
}
/**
* Uncurry a function of arity-8.
*
* @return An uncurried function.
*/
public static F>>>>>>>, F8> uncurryF8() {
return Function::uncurryF8;
}
/**
* Uncurry a function of arity-8.
*
* @param f The function to uncurry.
* @return An uncurried function.
*/
public static F8 uncurryF8(
final F>>>>>>> f) {
return (a, b, c, d, e, f$, g, h) -> f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g).f(h);
}
/**
* Binds the function in the second argument to the function in the first argument.
*
* @param ma A function whose argument type is the same as the argument type of the return value.
* @param f A function whose argument type is the same as the return type of ma,
* and yields the return value.
* @return A function that chains the given functions together such that the result of applying
* ma to the argument is given to f, yielding a function
* that is applied to the argument again.
*/
public static F bind(final F ma, final F> f) {
return m -> f.f(ma.f(m)).f(m);
}
/**
* Performs function application within a higher-order function (applicative functor pattern).
*
* @param cab The higher-order function to apply a function to.
* @param ca A function to apply within a higher-order function.
* @return A new function after applying the given higher-order function to the given function.
*/
public static F apply(final F> cab, final F ca) {
return apply(uncurryF2(cab), ca);
}
/**
* Performs function application within a higher-order function (applicative functor pattern).
*
* @param cab The higher-order function to apply a function to.
* @param ca A function to apply within a higher-order function.
* @return A new function after applying the given higher-order function to the given function.
*/
public static F apply(final F2 cab, final F ca) {
return c -> cab.f(c, ca.f(c));
}
/**
* Binds the given function f to the values of the given functions, with a final join.
*
* @param ca A function to bind f function to.
* @param cb A function to bind f function to.
* @param f The bound function to be composed with ca and then applied with cb
* @return A new function after performing the composition, then application.
*/
public static F bind(final F ca, final F cb, final F> f) {
return apply(compose(f, ca), cb);
}
/**
* Applies a given function over the arguments of another function of arity-2.
*
* @param a The function whose arguments to apply another function over.
* @param f The function to apply over the arguments of another function.
* @return A function whose arguments are fed through function f, before being passed to function a.
*/
public static F> on(final F> a, final F f) {
return compose(compose(Function.andThen().f(f), a), f);
}
/**
* Promotes a function of arity-2 to a higher-order function.
*
* @param f The function to promote.
* @return A function of arity-2 promoted to compose with two functions.
*/
public static F, F, F>> lift(final F> f) {
return curry((ca, cb) -> bind(ca, cb, f));
}
/**
* Joins two arguments of a function of arity-2 into one argument, yielding a function of arity-1.
*
* @param f A function whose arguments to join.
* @return A function of arity-1 whose argument is substituted for both parameters of f.
*/
public static F join(final F> f) {
return bind(f, Function.identity());
}
/**
* Partial application of the second argument to the supplied function to get a function of type
* A -> C. Same as flip(f).f(b).
*
* @param f The function to partially apply.
* @param b The value to apply to the function.
* @return A new function based on f with its second argument applied.
*/
public static F partialApply2(final F> f, final B b) {
return a -> uncurryF2(f).f(a, b);
}
/**
* Partial application of the third argument to the supplied function to get a function of type
* A -> B -> D.
*
* @param f The function to partially apply.
* @param c The value to apply to the function.
* @return A new function based on f with its third argument applied.
*/
public static F> partialApply3(final F>> f, final C c) {
return a -> b -> uncurryF3(f).f(a, b, c);
}
/**
* Partial application of the fourth argument to the supplied function to get a function of type
* A -> B -> C -> E.
*
* @param f The function to partially apply.
* @param d The value to apply to the function.
* @return A new function based on f with its fourth argument applied.
*/
public static F>> partialApply4(final F>>> f, final D d) {
return a -> b -> c -> uncurryF4(f).f(a, b, c, d);
}
/**
* Partial application of the fifth argument to the supplied function to get a function of type
* A -> B -> C -> D -> F$.
*
* @param f The function to partially apply.
* @param e The value to apply to the function.
* @return A new function based on f with its fifth argument applied.
*/
public static F>>> partialApply5(final F>>>> f,
final E e) {
return a -> b -> c -> d -> uncurryF5(f).f(a, b, c, d, e);
}
/**
* Partial application of the sixth argument to the supplied function to get a function of type
* A -> B -> C -> D -> E -> G.
*
* @param f The function to partially apply.
* @param f$ The value to apply to the function.
* @return A new function based on f with its sixth argument applied.
*/
public static F>>>> partialApply6(
final F>>>>> f, final F$ f$) {
return a -> b -> c -> d -> e -> uncurryF6(f).f(a, b, c, d, e, f$);
}
/**
* Partial application of the seventh argument to the supplied function to get a function of type
* A -> B -> C -> D -> E -> F$ -> H.
*
* @param f The function to partially apply.
* @param g The value to apply to the function.
* @return A new function based on f with its seventh argument applied.
*/
public static F>>>>> partialApply7(
final F>>>>>> f, final G g) {
return a -> b -> c -> d -> e -> f$ -> uncurryF7(f).f(a, b, c, d, e, f$, g);
}
/**
* Partial application of the eigth argument to the supplied function to get a function of type
* A -> B -> C -> D -> E -> F$ -> G -> I.
*
* @param f The function to partially apply.
* @param h The value to apply to the function.
* @return A new function based on f with its eigth argument applied.
*/
public static F>>>>>> partialApply8(
final F>>>>>>> f, final H h) {
return a -> b -> c -> d -> e -> f$ -> g -> uncurryF8(f).f(a, b, c, d, e, f$, g, h);
}
}