interface Lam<X, Y> {
Y apply(X x);
}
// http://en.wikipedia.org/wiki/SKI_combinator_calculus
class SKI {
public static <A, B, C> Lam<Lam<A, Lam<B, C>>, Lam<Lam<A, B>, Lam<A, C>>> s() {
return new Lam<Lam<A, Lam<B, C>>, Lam<Lam<A, B>, Lam<A, C>>>() {
public Lam<Lam<A, B>, Lam<A, C>> apply(final Lam<A, Lam<B, C>> f) {
return new Lam<Lam<A, B>, Lam<A, C>>() {
public Lam<A, C> apply(final Lam<A, B> g) {
return new Lam<A, C>() {
public C apply(final A a) {
return f.apply(a).apply(g.apply(a));
}
};
}
};
}
};
}
public static <A, B> Lam<A, Lam<B, A>> k() {
return new Lam<A, Lam<B, A>>() {
public Lam<B, A> apply(final A a) {
return new Lam<B, A>() {
public A apply(final B b) {
return a;
}
};
}
};
}
public static <A> Lam<A, A> i() {
return SKI.<A, Lam<A, A>, A>s().apply(SKI.<A, Lam<A, A>>k()).apply(SKI.<A, A>k());
}
}
This entry was posted
on Monday, February 8th, 2010 at 5:17 pm and is filed under Programming.
You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.
February 9th, 2010 at 1:23 am
Sick!
February 9th, 2010 at 1:28 am
A couple of questions though. Why not just use static final values instead of static methods? And why not define I as simply:
public static final i = new Lam() {public A apply(final A a){return a;}};
February 9th, 2010 at 10:55 am
Hi Runar,
They need to be methods because they are polymorphic. You cannot use type variables with values; they must be methods.