【发布时间】:2014-05-11 17:51:11
【问题描述】:
我尝试在 OCaml 中使用参数化类型,但它不起作用:(
在第一个文件“tree.ml”中,我定义了类型:
type 'a tree =
| Node of ('a tree)*('a tree)
| Leaf of 'a
在另一个文件“intTree.ml”中,我使用这个类型来定义一个类型t:
open Tree
type t = int tree
最后,我想在“main.ml”中的函数“size”中使用类型t:
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.
...
我知道它们是快速解决此错误的解决方案(例如,将“open Tree type t = int tree”放入 main.ml 而不是“open IntTree type t = IntTree.t”)但我需要使用以前的结构(出于其他原因......)。有解决办法吗?
谢谢
【问题讨论】:
-
你的
main.ml打开IntTree,所以它会得到那里定义的所有名称。但是,Leaf并没有在那里定义;它在Tree中定义。因此,正如 Kadaku 所说,您应该在您的main.ml中打开Tree。这看起来很麻烦,但那是因为你的模块太小了。在一个真实的项目中,你会控制更多的名字。 -
另外,我个人发现在大型项目中使用完全限定名称
Tree.Leaf更有帮助,而不是打开。
标签: types ocaml parameterized