Skip to content

Instantly share code, notes, and snippets.

Created September 12, 2013 20:53
Show Gist options
  • Save anonymous/6543643 to your computer and use it in GitHub Desktop.
Save anonymous/6543643 to your computer and use it in GitHub Desktop.
/*
* This software and ancillary information (herein called "SOFTWARE") called
* Functional.java is made available under the terms described here. The SOFTWARE has
* been approved for release with associated LA-CC number 05-053.
* Unless otherwise indicated, this SOFTWARE has been authored by an employee or employees of
* the University of California, operator of the Los Alamos National Laboratory under Contract No.
* W-7405-ENG-36 with the U.S. Department of Energy. The U.S. Government has rights to use,
* reproduce, and distribute this SOFTWARE. The public may copy, distribute, prepare
* derivative works and publicly display this SOFTWARE without charge, provided that this
* Notice and any statement of authorship are reproduced on all copies. Neither the Government
* nor the University makes any warranty, express or implied, or assumes any liability or
* responsibility for the use of this SOFTWARE.
* If SOFTWARE is modified to produce derivative works, such modified SOFTWARE should be
* clearly marked, so as not to confuse it with the version available from LANL.
*/
/**
* @file Partial.java
* @author Mark Zander
* @date 15-Apr-2005
*/
package fcn;
/**
* Partial function objects.
* This is a holder class for partial function objects.
* Partial function objects have had at least one of their arguments
* applied, but not yet all of them. They store the already applied
* arguments in an ArgList. If a partial function of three arguments
* has another argument applied it creates a partial function object
* of 2 arguments.
*/
class Partial {
/**
* Partial function object with one argument remaining.
* @param <T> is the type of the remaining argument
* @param <R> is the return type of the function to be called
* @param <A> is the type of the current ArgList
* @param <E> is the type of the Execute object
*/
public static class O1<T, R, A, E extends Executioner<R, ArgList<T, A>>>
extends Function.O1<T, R>
implements Fcn<T, R> {
A arglist;
E execute;
/**
* Create a new partial function object with one argument remaining.
* @param arglist is the current ArgList
* @param execute is the Execute object
*/
public O1(A arglist, E execute) {
this.arglist = arglist;
this.execute = execute;
}
/**
* Adds the next argument to the ArgList and calls the Execute
* object.
* @param a is the last function argument
* @return the result of the called function
*/
public R x(T a) {
return execute.calls(new ArgList<T, A>(a, arglist));
}
/**
* Immediate call to underlying function object given the
* remaining function arguments.
* @param a is the last function argument
* @return the result of the called function
*/
public R call(T a) {
return execute.calls(new ArgList<T, A>(a, arglist));
}
}
/**
* Makes a partial function object with one argument remaining.
* @param <T0> is the type of the previous function argument
* @param <T> is the type of the next function argument
* @param <R> is the return type of the final function
* @param <A> is the type of the ArgList
* @param <E> is the type ofthe Execute object
* @param arglist is the arglist
* @param execute is the execute object
* @param f is the current function object,
* used to infer types needed by this function
* @return the function object with one argument remaining
*/
public static <T0, T, R, A, E extends Executioner<R, ArgList<T, A>>>
Function.O1<T, R>
make1(A arglist, E execute, Fcn<T0, Fcn<T, R>> f) {
return new O1<T, R, A, E>(arglist, execute);
}
/**
* Partial function object with 2 arguments remaining.
* @param <T1> type of the first argument remaining
* @param <T2> type of the second argument remaining
* @param <R> return type of the function
* @param <A> type of the ArgList of arguments collected so far
* @param <E> type of the Executioner
*/
public static class O2
<T1, T2, R, A, E extends Executioner<R, ArgList<T2, ArgList<T1, A>>>>
extends Function.O2<T1, T2, R>
implements Fcn<T1, Fcn<T2, R>> {
A arglist;
E execute;
/**
* Create a new partial function object with two arguments remaining.
* @param arglist is an ArgList of the arguments collected so far
* @param execute is the Executioner called when the ArgList is
* complete.
*/
public O2(A arglist, E execute) {
this.arglist = arglist;
this.execute = execute;
}
/**
* Adds the next argument to the ArgList and creates a partial
* function object with one argument left.
* @param a is the second to last function argument
* @return the a partial function object needing one more
* argument
*/
public Function.O1<T2, R> x(T1 a) {
return make1(new ArgList<T1, A>(a, arglist), execute, this);
}
/**
* Immediate call to underlying function object given the
* remaining function arguments.
* @param a1 is the second to last function argument
* @param a2 is the last function argument
* @return the result of the called function
*/
public R call(T1 a1, T2 a2) {
return execute.calls(ArgList.make(a2, a1, arglist));
}
}
/**
* Makes a partial function object with two arguments remaining.
* @param <T0> is the type of the previous function argument
* @param <T1> is the type of the next function argument
* @param <T2> is the type of the final function argument
* @param <R> is the return type of the function object
* @param <A> is the type of the current ArgList
* @param <E> is the type of the Executioner
* @param arglist is the current ArgList
* @param execute is the executioner
* @param f is the current function object,
* used to infer types needed by this function
* @return the function object with two arguments remaining
*/
public static
<T0, T1, T2, R, A, E extends Executioner<R, ArgList<T2, ArgList<T1, A>>>>
// Fcn<T1, Fcn<T2, R>>
Function.O2<T1, T2, R>
make2(A arglist, E execute, Fcn<T0, Fcn<T1, Fcn<T2, R>>> f) {
return new O2<T1, T2, R, A, E>(arglist, execute);
}
/**
* Partial function object with 3 arguments remaining.
* @param <T1> type of the first argument remaining
* @param <T2> type of the second argument remaining
* @param <T3> type of the third argument remaining
* @param <R> return type of the function
* @param <A> type of the ArgList of arguments collected so far
* @param <E> type of the Executioner
*/
public static class O3
<T1, T2, T3, R, A, E extends
Executioner<R, ArgList<T3, ArgList<T2, ArgList<T1, A>>>>>
extends Function.O3<T1, T2, T3, R>
implements Fcn<T1, Fcn<T2, Fcn<T3, R>>> {
A arglist;
E execute;
/**
* Create a new partial function object with 3 arguments remaining.
* @param arglist is an ArgList of the arguments collected so far
* @param execute is the Executioner called when the ArgList is
* complete.
*/
public O3(A arglist, E execute) {
this.arglist = arglist;
this.execute = execute;
}
/**
* Adds the next argument to the ArgList and creates a partial
* function object with 2 arguments left.
* @param a is the third to last function argument
* @return the a partial function object needing 2 more
* arguments
*/
// public Fcn<T2, Fcn<T3, R>> x(T1 a) {
public Function.O2<T2, T3, R> x(T1 a) {
return make2(new ArgList<T1, A>(a, arglist), execute, this);
}
/**
* Immediate call to underlying function object given the
* remaining function arguments.
* @param a1 is the third to last function argument
* @param a2 is the second to last function argument
* @param a3 is the last function argument
* @return the result of the called function
*/
public R call(T1 a1, T2 a2, T3 a3) {
return execute.calls(ArgList.make(a3, a2, a1, arglist));
}
}
/**
* Makes a partial function object with 3 arguments remaining.
* @param <T0> is the type of the previous function argument
* @param <T1> is the type of the next function argument
* @param <T2> is the type of the second remaining function
* argument
* @param <T3> is the type of the final function argument
* @param <R> is the return type of the function object
* @param <A> is the type of the current ArgList
* @param <E> is the type of the Executioner
* @param arglist is the current ArgList
* @param execute is the executioner
* @param f is the current function object,
* used to infer types needed by this function
* @return the function object with 3 arguments remaining
*/
public static
<T0, T1, T2, T3, R, A, E extends
Executioner<R, ArgList<T3, ArgList<T2, ArgList<T1, A>>>>>
// Fcn<T1, Fcn<T2, Fcn<T3, R>>>
Function.O3<T1, T2, T3, R>
make3(A arglist, E execute, Fcn<T0, Fcn<T1, Fcn<T2, Fcn<T3, R>>>> f) {
return new O3<T1, T2, T3, R, A, E>(arglist, execute);
}
/**
* Partial function object with 3 arguments remaining.
* @param <T1> type of the first argument remaining
* @param <T2> type of the second argument remaining
* @param <T3> type of the third argument remaining
* @param <T4> type of the fourth argument remaining
* @param <R> return type of the function
* @param <A> type of the ArgList of arguments collected so far
* @param <E> type of the Executioner
*/
public static class O4
<T1, T2, T3, T4, R, A, E extends
Executioner<R, ArgList<T4, ArgList<T3, ArgList<T2, ArgList<T1, A>>>>>>
extends Function.O4<T1, T2, T3, T4, R>
implements Fcn<T1, Fcn<T2, Fcn<T3, Fcn<T4, R>>>> {
A arglist;
E execute;
/**
* Create a new partial function object with 4 arguments remaining.
* @param arglist is an ArgList of the arguments collected so far
* @param execute is the Executioner called when the ArgList is
* complete.
*/
public O4(A arglist, E execute) {
this.arglist = arglist;
this.execute = execute;
}
/**
* Adds the next argument to the ArgList and creates a partial
* function object with 3 arguments left.
* @param a is the fourth to last function argument
* @return the a partial function object needing 3 more
* arguments
*/
// public Fcn<T2, Fcn<T3, Fcn<T4, R>>> x(T1 a) {
public Function.O3<T2, T3, T4, R> x(T1 a) {
return make3(new ArgList<T1, A>(a, arglist), execute, this);
}
/**
* Immediate call to underlying function object given the
* remaining function arguments.
* @param a1 is the fourth to last function argument
* @param a2 is the third to last function argument
* @param a3 is the second to last function argument
* @param a4 is the last function argument
* @return the result of the called function
*/
public R call(T1 a1, T2 a2, T3 a3, T4 a4) {
return execute.calls(ArgList.make(a4, a3, a2, a1, arglist));
}
}
/**
* Makes a partial function object with 4 arguments remaining.
* @param <T0> is the type of the previous function argument
* @param <T1> is the type of the next function argument
* @param <T2> is the type of the second remaining function
* argument
* @param <T3> is the type of the third remaining function
* argument
* @param <T4> is the type of the final function argument
* @param <R> is the return type of the function object
* @param <A> is the type of the current ArgList
* @param <E> is the type of the Executioner
* @param arglist is the current ArgList
* @param execute is the executioner
* @param f is the current function object,
* used to infer types needed by this function
* @return the function object with 4 arguments remaining
*/
public static
<T0, T1, T2, T3, T4, R, A, E extends
Executioner<R, ArgList<T4, ArgList<T3, ArgList<T2, ArgList<T1, A>>>>>>
// Fcn<T1, Fcn<T2, Fcn<T3, Fcn<T4, R>>>>
Function.O4<T1, T2, T3, T4, R>
make4(A arglist, E execute,
Fcn<T0, Fcn<T1, Fcn<T2, Fcn<T3, Fcn<T4, R>>>>> f) {
return new O4<T1, T2, T3, T4, R, A, E>(arglist, execute);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment