我尝试在 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”)但我需要使用以前的结构(由于其他原因...)。有解决办法吗?
谢谢
最佳答案
您需要 open Tree
在 main.ml 中。您不需要复制和粘贴类型声明。在你的代码编译器试图猜测你的想法。这就是为什么手动添加类型注释可以部分解决问题的原因。
编译器看到您期望 tree
为 r
类型,它查看类型 r
来自模块 IntTree
(由你打开),它知道可能我们在 Tree
中有这个构造函数模块。它打开它并发出警告。此功能是最近才引入的,所以不要惊讶于您不知道它。
关于types - OCaml 中的参数化类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23595967/