Reputation: 719
I try to use parameterized types in OCaml but it doesnt't work :(
In a first file "tree.ml" I define the type :
type 'a tree =
| Node of ('a tree)*('a tree)
| Leaf of 'a
In another file "intTree.ml", I use this type to define a type t :
open Tree
type t = int tree
Finally, I want to use the type t in a function "size" in "main.ml" :
open IntTree
type r = IntTree.t
let rec size tree = match tree with
| Leaf k -> 0
| Node (t1,t2) -> 1 + size t1 + size t2
When I try to compile these files, I obtain the following error :
File "main.ml", line 6, characters 4-8:
Error: Unbound constructor Leaf
If i defined "main.mli", it doesn't change anything :
type r
val size : r -> int
If I put :
let rec size (tree : r) = match tree with
| Leaf k -> 0
| Node (t1,t2) -> 1 + size t1 + size t2
i have :
Warning 40: Leaf was selected from type Tree.tree.
It is not visible in the current scope, and will not
be selected if the type becomes unknown.
...
I know they are solutions to solve this error quickly (for example, putting "open Tree type t = int tree" in main.ml instead of "open IntTree type t = IntTree.t") but I need to use the previous structure (for other reasons...). Is there a solution ?
Thank you
Upvotes: 5
Views: 2610
Reputation: 1044
While adding open Tree
in "main.ml" will solve the problem, it might be preferable to write the following to avoid polluting "main.ml" with eventual irrelevant definitions from "Tree.mli":
let rec size tree = match tree with
| Tree.Leaf k -> 0
| Tree.Node (t1,t2) -> 1 + size t1 + size t2
Upvotes: 0
Reputation: 66818
Another solution is to change this:
open Tree
to this:
include Tree
in intTree.ml
. The idea is that intTree
then becomes self-contained by including all the definitions from Tree
.
Upvotes: 5
Reputation: 2839
You need to open Tree
in main.ml. You don't need to copy and paste type declaration. In you code compiler tries to guess what is on your mind. That's why adding type annotation manually partially solves the problem.
Compiler sees that you expect tree
to be of type r
, it looks at type r
from module IntTree
(which is opened by you) and there it understands that probably we have this constructors in Tree
module. It opens it with a warning. This feature was introduced rather recently, so don't be suprized that you are not aware of it.
Upvotes: 5