package org.enumerable.lambda; /** * A function that takes one argument. */ @SuppressWarnings("serial") public abstract class Fn1<A1, R> extends Fn0<R> { /** * The identity function, returns the argument passed into it. */ public static <A1> Fn1<A1, A1> identity() { return new Fn1<A1, A1>() { public A1 call(A1 a1) { return a1; } }; } public abstract R call(A1 a1); public R call() { return call(default$1()); } protected A1 default$1() { return null; } @SuppressWarnings("unchecked") public R apply(Object... args) { if (args.length >= 1) return call((A1) args[0]); return super.apply(args); } /** * Partial application, returns a {@link Fn0} which calls this function with * a1 as the argument. */ public Fn0<R> partial(final A1 a1) { return new Fn0<R>() { public R call() { return Fn1.this.call(a1); } }; } /** * Function composition, returns a {@link Fn0} that calls this function with * the result of f. */ public Fn0<R> compose(final Fn0<? extends A1> f) { return new Fn0<R>() { public R call() { return Fn1.this.call(f.call()); } }; } /** * Function composition, returns a {@link Fn1} that calls this function with * the result of f called with a1. */ public <X> Fn1<X, R> compose(final Fn1<X, ? extends A1> f) { return new Fn1<X, R>() { public R call(X a1) { return Fn1.this.call(f.call(a1)); } }; } /** * Function composition, returns a {@link Fn2} that calls this function with * the result of f called with a1 and a2. */ public <X, Y> Fn2<X, Y, R> compose(final Fn2<X, Y, ? extends A1> f) { return new Fn2<X, Y, R>() { public R call(X a1, Y a2) { return Fn1.this.call(f.call(a1, a2)); } }; } /** * Function composition, returns a {@link Fn3} that calls this function with * the result of f called with a1, a2 and a3. */ public <X, Y, Z> Fn3<X, Y, Z, R> compose(final Fn3<X, Y, Z, ? extends A1> f) { return new Fn3<X, Y, Z, R>() { public R call(X a1, Y a2, Z a3) { return Fn1.this.call(f.call(a1, a2, a3)); } }; } public Fn1<A1, Boolean> complement() { return new Fn1<A1, Boolean>() { public Boolean call(A1 a1) { return isFalseOrNull(Fn1.this.call(a1)); } }; } public int arity() { return 1; } }