Open runarorama opened 9 years ago
@runarorama Thank you for the post. I've found it very useful for my java8 projects. I've used your approach and went little bit further by decomposing matched objects:
int depth(Tree t) {
return t.match(empty -> 0,
leaf(n -> 1),
node((left, right) -> 1 + max(depth(left), depth(right))));
}
Where leaf
and node
are helper functions:
<T> Function<Leaf, T> leaf(Function<Integer, T> function) {
return leaf -> function.apply(leaf.n);
}
<T> Function<Node, T> node(BiFunction<Tree, Tree, T> function) {
return node -> function.apply(node.left, node.right);
}
But this approach has limitation - standard java8 library has only unary and binary functional objects. Currying can help but it less readable
int depth(Tree t) {
return t.match(empty -> 0,
leaf(n -> 1),
node(left -> right -> 1 + max(depth(left), depth(right))));
}
<T> Function<Node, T> node(Function<Tree, Function<Tree, T>> function) {
return node -> function.apply(node.left).apply(node.right);
}
I was just redirected here from the JOOQ blog. Thanks for the post. Perhaps you'd be interested in cyclops-react, a functional library that implements structural pattern matching for Java through java.util.Predicate
, so you can pattern-match in your code wherever a predicate is accepted. Resulting code is not quite as terse as yours, but you don't need to implement anything in your own datatypes. Cyclops is also here on GitHub (I'm not involved). And here's the article about the pattern-matching stuff.
-- Sebastian
Hello, I just stumbled upon your article, and found it very interesting ; I'm myself trying to learn FP while being a OOP Java programmer, and right now it's not exactly easy. I wanted to leave a comment because, in this article, you're saying the visitor pattern is ugly, but the visitor interface is just an aggregate of the threes lambdas you're passing around in the "good" solution ; isn't a data object objectively better and easier to extends than passing 3 arguments everywhere ? Or is it just me that is seeing everything through my thick OOP lenses ?
Yes! So much Java code is a mess because of not implementing proper Sum types.
Readers of this post might be interested in Derive4j - https://github.com/derive4j/derive4j - a project that try to industrialize a variant of this technique (through annotation processing).