我尝试在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 t= IntTree“放置在main.ml中而不是"open t= IntTree.t"),但我需要使用前面的结构(出于其他原因.)。有解决办法吗?
谢谢
发布于 2014-05-11 18:35:37
您需要在open Tree中使用main.ml。您不需要复制和粘贴类型声明。在您的代码编译器试图猜测什么是您的想法。这就是为什么手动添加类型注释部分解决了问题。
编译器看到您期望tree是r类型,它从模块IntTree (由您打开)中查看r类型,在那里它了解到可能我们在Tree模块中有这个构造函数。它会带着警告打开它。这个特性是最近引入的,所以不要被认为你没有意识到它。
发布于 2014-05-11 18:45:46
另一种解决办法是改变这种情况:
open Tree对此:
include Tree在intTree.ml中。这个想法是,intTree通过包含来自Tree的所有定义而变得自成体系。
发布于 2015-03-11 11:16:15
虽然在“open Tree”中添加main.ml可以解决这个问题,但最好编写以下代码以避免使用“Tree.mli”中最终不相关的定义来污染"main.ml“:
let rec size tree = match tree with
| Tree.Leaf k -> 0
| Tree.Node (t1,t2) -> 1 + size t1 + size t2https://stackoverflow.com/questions/23595967
复制相似问题