Haskellでは、次のデータ型を定義できます。
data Tree = Empty
| Leaf Int
| Node Tree Tree
次に、次のような多相関数を記述します。
depth :: Tree -> Int
depth Empty = 0
depth (Leaf n) = 1
depth (Node l r) = 1 + max (depth l) (depth r)
Java では、インターフェイスを使用して代数データ型をエミュレートできます。
interface Tree {}
class Empty implements Tree {}
class Leaf implements Tree { int n; }
class Node implements Tree { Tree l; Tree r; }
しかし、Haskell のようなポリモーフィズムを使用しようとすると、エラーが発生します。
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)'
}
これを克服する正しい方法は、各クラスにメソッドを配置する ことです。しかし、そこに置きたくない場合はどうすればよいですか?たとえば、メソッドはクラスに直接関連していない可能性があり、それをクラスに追加するとビジネス ロジックが壊れます。または、さらに悪いことに、私がアクセスできないサードパーティのライブラリに書かれている可能性があります。この場合、ADT のようなポリモーピズムを実装する最も簡単な方法は何ですか?depth()
depth()
Tree
Tree
念のため、現時点では次の構文を使用していますが、これは明らかに好ましくありません。
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());
}