ADT-like polymorphism in Java (without altering class)
Posted
by
ffriend
on Stack Overflow
See other posts from Stack Overflow
or by ffriend
Published on 2012-10-05T20:53:42Z
Indexed on
2012/10/05
21:37 UTC
Read the original article
Hit count: 479
In Haskell I can define following data type:
data Tree = Empty
| Leaf Int
| Node Tree Tree
and then write polymorphic function like this:
depth :: Tree -> Int
depth Empty = 0
depth (Leaf n) = 1
depth (Node l r) = 1 + max (depth l) (depth r)
In Java I can emulate algebraic data types with interfaces:
interface Tree {}
class Empty implements Tree {}
class Leaf implements Tree { int n; }
class Node implements Tree { Tree l; Tree r; }
But if I try to use Haskell-like polymorphism, I get an error:
int depth(Empty node) {
return 0;
}
int depth(Leaf node) {
return 1;
}
int depth(Node node) {
return 1 + Math.max(depth(node.l), depth(node.r)); // ERROR: Cannot resolve method 'depth(Tree)'
}
Correct way to overcome this is to put method depth()
to each class. But what if I don't want to put it there? For example, method depth()
may be not directly related to Tree
and adding it to class would break business logic. Or, even worse, Tree
may be written in 3rd party library that I don't have access to. In this case, what is the simplest way to implement ADT-like polymorpism?
Just in case, for the moment I'm using following syntax, which is obviously ill-favored:
int depth(Tree tree) {
if (tree instanceof Empty) depth((Empty)tree)
if (tree instanceof Leaf) depth((Leaf)tree);
if (tree instanceof Node) depth((Node)tree);
else throw new RuntimeException("Don't know how to find depth of " + tree.getClass());
}
© Stack Overflow or respective owner