OCaml中的参数化类型

per*_*ate 5 ocaml types parameterized

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

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

type 'a tree =
  | Node of ('a tree)*('a tree) 
  | Leaf of 'a  
Run Code Online (Sandbox Code Playgroud)

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

open Tree
type t = int tree
Run Code Online (Sandbox Code Playgroud)

最后,我想在"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
Run Code Online (Sandbox Code Playgroud)

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

File "main.ml", line 6, characters 4-8:
Error: Unbound constructor Leaf
Run Code Online (Sandbox Code Playgroud)

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

type r

val size : r -> int
Run Code Online (Sandbox Code Playgroud)

如果我把:

let rec size (tree : r) = match tree with
  | Leaf k -> 0
  | Node (t1,t2) -> 1 + size t1 + size t2
Run Code Online (Sandbox Code Playgroud)

我有 :

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.
...
Run Code Online (Sandbox Code Playgroud)

我知道它们是快速解决此错误的解决方案(例如,在main.ml中放置"open tree type t = int tree"而不是"open IntTree type t = IntTree.t")但我需要使用之前的结构(由于其他原因......).有解决方案吗?

谢谢

Kak*_*adu 5

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

编译器看到你期望tree是类型r,它r从模块IntTree(由你打开)查看类型,并且它理解我们可能在Tree模块中有这个构造函数.它会打开警告.这个功能最近才被引入,所以不要因为你没有意识到这一点.


Jef*_*eld 5

另一种解决方案是改变这一点:

open Tree
Run Code Online (Sandbox Code Playgroud)

对此:

include Tree
Run Code Online (Sandbox Code Playgroud)

intTree.ml。这个想法是intTree通过包含来自Tree.