OCaml中的参数化类型

时间:2014-05-11 17:51:11

标签: types ocaml parameterized

我尝试在OCaml中使用参数化类型,但它不起作用:(

在第一个文件" tree.ml"我定义了类型:

type 'a tree =
  | Node of ('a tree)*('a tree) 
  | Leaf of 'a  

在另一个文件" intTree.ml"中,我使用此类型来定义类型t:

open Tree
type t = int tree

最后,我想在函数中使用类型t" 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

当我尝试编译这些文件时,我收到以下错误:

File "main.ml", line 6, characters 4-8:
Error: Unbound constructor Leaf

如果我定义了" main.mli",它不会改变任何东西:

type r

val size : r -> int

如果我把:

let rec size (tree : r) = match tree with
  | Leaf k -> 0
  | Node (t1,t2) -> 1 + size t1 + size t2
我有:

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.
...

我知道它们是快速解决此错误的解决方案(例如,将#34;打开树类型t = int树"在main.ml而不是"打开IntTree类型t = IntTree.t& #34;)但我需要使用以前的结构(出于其他原因......)。有解决方案吗?

谢谢

3 个答案:

答案 0 :(得分:5)

你需要在main.ml中open Tree。您不需要复制和粘贴类型声明。在你的代码编译器试图猜测你的想法。这就是为什么手动添加类型注释部分解决问题的原因。

编译器发现您希望tree属于r类型,它会查看模块r中的类型IntTree(由您打开)并在那里了解可能我们在Tree模块中有这个构造函数。它会打开警告。这个功能最近才推出,所以不要因为你没有意识到这一点。

答案 1 :(得分:4)

另一个解决方案是改变这个:

open Tree

到此:

include Tree
intTree.ml中的

。我们的想法是intTree通过包含Tree中的所有定义而变为自包含。

答案 2 :(得分:0)

在" main.ml"中添加open Tree将解决问题,可能最好写下以避免污染" main.ml"来自" Tree.mli"的最终无关定义:

let rec size tree = match tree with
  | Tree.Leaf k -> 0
  | Tree.Node (t1,t2) -> 1 + size t1 + size t2