Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parameterized types in OCaml

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

like image 352
permanganate Avatar asked May 11 '14 17:05

permanganate


People also ask

What is a tuple in OCaml?

Every function in OCaml takes exactly one value and returns exactly one result. For instance, our squareRoot function takes one float value and returns one float value. The advantage of always taking one argument and returning one result is that the language is extremely uniform.

What is a variant in OCaml?

Variant types are one of the most useful features of OCaml and also one of the most unusual. They let you represent data that may take on multiple different forms, where each form is marked by an explicit tag.

What is pattern matching in OCaml?

Pattern matching comes up in several places in OCaml: as a powerful control structure combining a multi-armed conditional, unification, data destructuring and variable binding; as a shortcut way of defining functions by case analysis; and as a way of handling exceptions.


2 Answers

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.

like image 132
Kakadu Avatar answered Nov 15 '22 09:11

Kakadu


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.

like image 38
Jeffrey Scofield Avatar answered Nov 15 '22 08:11

Jeffrey Scofield