I use Church encoding quite a lot in Java for a poor mans pattern matching / ADTs. It's one of the more useful patterns I use.
import java.util.function.Function;
public abstract class Tree {
// Constructor private so the type is sealed.
private Tree() {}
public abstract <T> T match(Function<Empty, T> a, Function<Leaf, T> b, Function<Node, T> c);
public static final class Empty extends Tree {
public <T> T match(Function<Empty, T> a, Function<Leaf, T> b, Function<Node, T> c) {
return a.apply(this);
}
public Empty() {}
}
public static final class Leaf extends Tree {
public final int n;
public <T> T match(Function<Empty, T> a, Function<Leaf, T> b, Function<Node, T> c) {
return b.apply(this);
}
public Leaf(int n) { this.n = n; }
}
public static final class Node extends Tree {
public final Tree left;
public final Tree right;
public <T> T match(Function<Empty, T> a, Function<Leaf, T> b, Function<Node, T> c) {
return c.apply(this);
}
public Node(Tree left, Tree right) {
this.left = left; this.right = right;
}
}
}