首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OCaml中的参数化类型

OCaml中的参数化类型
EN

Stack Overflow用户
提问于 2014-05-11 17:51:11
回答 3查看 2.2K关注 0票数 5

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

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

代码语言:javascript
复制
type 'a tree =
  | Node of ('a tree)*('a tree) 
  | Leaf of 'a  

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

代码语言:javascript
复制
open Tree
type t = int tree

最后,我想在"main.ml“中的函数"size”中使用t类型:

代码语言:javascript
复制
open IntTree

type r = IntTree.t

let rec size tree = match tree with
  | Leaf k -> 0
  | Node (t1,t2) -> 1 + size t1 + size t2

当我试图编译这些文件时,会获得以下错误:

代码语言:javascript
复制
File "main.ml", line 6, characters 4-8:
Error: Unbound constructor Leaf

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

代码语言:javascript
复制
type r

val size : r -> int

如果我说:

代码语言:javascript
复制
let rec size (tree : r) = match tree with
  | Leaf k -> 0
  | Node (t1,t2) -> 1 + size t1 + size t2

我有:

代码语言:javascript
复制
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"),但我需要使用前面的结构(出于其他原因.)。有解决办法吗?

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-11 18:35:37

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

编译器看到您期望treer类型,它从模块IntTree (由您打开)中查看r类型,在那里它了解到可能我们在Tree模块中有这个构造函数。它会带着警告打开它。这个特性是最近引入的,所以不要被认为你没有意识到它。

票数 5
EN

Stack Overflow用户

发布于 2014-05-11 18:45:46

另一种解决办法是改变这种情况:

代码语言:javascript
复制
open Tree

对此:

代码语言:javascript
复制
include Tree

intTree.ml中。这个想法是,intTree通过包含来自Tree的所有定义而变得自成体系。

票数 5
EN

Stack Overflow用户

发布于 2015-03-11 11:16:15

虽然在“open Tree”中添加main.ml可以解决这个问题,但最好编写以下代码以避免使用“Tree.mli”中最终不相关的定义来污染"main.ml“:

代码语言:javascript
复制
let rec size tree = match tree with
  | Tree.Leaf k -> 0
  | Tree.Node (t1,t2) -> 1 + size t1 + size t2
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23595967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档