I’m trying to learn more about OCaml’s object system by implementing the classic OOP visitor pattern. Specifically, I’m trying to translate the code in this blog post: logji: Correcting the Visitor pattern.. A simplified version (in Java) goes as follows:
interface Tree {
public <B> B accept(TreeVisitor<B> v);
}
interface TreeVisitor<B> {
public B visitLeaf(Leaf t);
}
class Leaf implements Tree {
public final int value;
public Leaf(int value) {
this.value = value;
}
public <B> B accept(TreeVisitor<B> v) {
return v.visitLeaf(this);
}
}
My naive translation doesn’t compile:
class virtual tree =
object
method virtual accept : 'a . 'a tree_visitor -> 'a
end
and virtual ['a] tree_visitor =
object
method virtual visit_leaf : (leaf -> 'a)
end
and leaf (i : int) =
object (self)
method get = i
method accept (v : 'a tree_visitor) : 'a =
v#visit_leaf (self :> leaf)
end
The error I get is:
File "visitor.ml", line 3, characters 28-54:
3 | method virtual accept : 'a . 'a tree_visitor -> 'a
^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: The universal type variable 'a cannot be generalized:
it escapes its scope.
When I leave off the 'a .
it still doesn’t compile. How do I fix this example? I know of the visitor library, which is much more sophisticated than this, so I’m pretty sure there is a way to fix this. Any help would be appreciated!