Types OCaml中的参数化类型
我尝试在OCaml中使用参数化类型,但不起作用:( 在第一个文件“tree.ml”中,我定义了类型:Types OCaml中的参数化类型,types,ocaml,parameterized,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 最后,我想在“main.ml”中的函数“size”中使用类型t: 当我试图编译这些文件时,我得到以下错误: File "main.ml", l
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:
当我试图编译这些文件时,我得到以下错误:
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.
...
我知道它们是快速解决此错误的解决方案(例如,在main.ml中放置“open-Tree-type t=int-Tree”而不是“open-int-Tree-type t=int-Tree.t”),但我需要使用前面的结构(出于其他原因…),有解决方案吗
谢谢您需要
在main.ml中打开树
。您不需要复制和粘贴类型声明。在您的代码中,编译器尝试猜测您的想法。这就是为什么手动添加类型注释部分解决了问题
编译器看到您期望
tree
为r
类型,它从模块IntTree
中查看类型r
(由您打开)在那里,它了解到可能我们在树模块中有此构造函数。它打开时会发出警告。此功能是最近引入的,因此不要担心您没有意识到它。另一个解决方案是更改此选项:
open Tree
为此:
include Tree
在intTree.ml
中,想法是intTree
通过包含Tree
中的所有定义而变得自包含。在“main.ml”中添加opentree
将解决此问题,最好编写以下内容以避免污染“main.ml”使用“Tree.mli”中最终不相关的定义:
你的main.ml
打开IntTree
,因此它得到了所有在那里定义的名称。然而,Leaf
没有在那里定义;它是在树中定义的。因此,正如Kadaku所说,你应该在main.ml
中打开树。这看起来很麻烦,但那是因为你的模块太小了。在真正的pr中您将有更多的名称需要控制。此外,我个人发现,在大型项目中使用完全限定的名称,Tree.Leaf
,比打开名称更有帮助。
include Tree
let rec size tree = match tree with
| Tree.Leaf k -> 0
| Tree.Node (t1,t2) -> 1 + size t1 + size t2