Apply.java
package no.motif.f;
/**
* Utilities to adapt how functions are invoked.
*/
public final class Apply {
/**
* Convert an {@link Fn} to a {@link Do}. This is only usable for <code>Fns</code> which
* performs some kind of side effect, and you need to pass it somewhere which expects a
* <code>Do</code>.
*
* @param fn The {@link Fn} to apply as a <code>Do</code>.
* @return The resulting {@link Do}
*/
public static final <I> Do<I> justSideEffectOf(final Fn<I, ?> fn) {
return new Do<I>() { @Override public void with(I value) { fn.$(value); }}; }
/**
* Transform a function taking 2 arguments to another function where
* the argument order is reversed.
*
* @param fn2 the function
* @return a new {@link Fn2} where the argument order is reversed.
*/
public static final <I1, I2, O> Fn2<I2, I1, O> argsReversed(final Fn2<I1, I2, O> fn2) {
return new Fn2<I2, I1, O>() { @Override public O $(I2 second, I1 first) { return fn2.$(first, second); }}; }
/**
* {@link PartialApplication Partially apply} a {@link Fn2 function taking 2 arguments}.
*
*
* @param fn2 The function to partially apply.
* @return use {@link PartialApplication#of(Object) of()}
* to partially invoke <code>fn2</code> and yield an {@link Fn}
*
* @see PartialApplication
*/
public static final <I1, I2, O> PartialApplication<Fn2<I1, I2, O>, I1, Fn<I2, O>> partially(Fn2<I1, I2, O> fn2) { return new PartialApplication<Fn2<I1, I2, O>, I1, Fn<I2,O>>(fn2) {
@Override public Fn<I2, O> partiallyApply(final Fn2<I1, I2, O> fn2, final Fn0<I1> v1) { return new Fn<I2, O>() {
@Override public O $(I2 v2) { return fn2.$(v1.$(), v2); }}; }}; }
/**
* {@link PartialApplication Partially apply} a {@link Fn function taking 1 argument}.
*
* @param fn The function to partially apply.
* @return use {@link PartialApplication#of(Object) of()}
* to partially invoke <code>fn</code> and yield an {@link Fn0}
*
* @see PartialApplication
*/
public static final <I, O> PartialApplication<Fn<I, O>, I, Fn0<O>> partially(Fn<I, O> fn) { return new PartialApplication<Fn<I, O>, I, Fn0<O>>(fn) {
@Override public Fn0<O> partiallyApply(final Fn<I, O> fn, final Fn0<I> v1) { return new Fn0<O>() {
@Override public O $() { return fn.$(v1.$()); }}; }}; }
private Apply() {}
}