Skip to content

Instantly share code, notes, and snippets.

@lambder
Forked from aruld/YFact.java
Created March 27, 2014 10:42
Show Gist options
  • Save lambder/9804763 to your computer and use it in GitHub Desktop.
Save lambder/9804763 to your computer and use it in GitHub Desktop.
//based on code from http://www.arcfn.com/2009/03/y-combinator-in-arc-and-java.html and the generic version https://gist.github.com/2571928
class YFact {
// T function returning a T
// T -> T
public static interface Func<T> {
T apply(T n);
}
// Higher-order function returning a T function
// F: F -> (T -> T)
private static interface FuncToTFunc<T> {
Func<T> apply(FuncToTFunc<T> x);
}
//Next comes the meat. We define the Y combinator, apply it to the factorial input function, and apply the result to the input argument. The result is the factorial.
// Formulation : λr.(λf.(f f)) λf.(r λx.((f f) x))
public static <T> Func<T> Y(final Func<Func<T>> r) {
return ((FuncToTFunc<T>) f -> f.apply(f))
.apply(
f -> r.apply(
x -> f.apply(f).apply(x)));
}
public static void main(String args[]) {
System.out.println(
// Y combinator
Y(
// Recursive function generator
new Func<Func<Integer>>() {
public Func<Integer> apply(final Func<Integer> f) {
return n -> n == 0 ? 1 : n * f.apply(n - 1);
}
}
).apply(
// Argument
Integer.parseInt(args[0])));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment