如何访问OCaml递归模块中定义的类型的字段?

时间:2015-04-10 09:39:34

标签: recursion types module field ocaml

我正在研究OCaml中的递归模块,我在访问类型字段时遇到了一些麻烦。

如果我尝试:

module A = struct type t = { name : string; } end
module A2 = 
  struct 
    include A 
    let getName (x:t) = x.name 
  end;;

一切都很好。但是,我需要一个更复杂的类型,迫使我在递归模块中定义我的类型。

module rec B:Set.OrderedType = 
  struct 
    type t = {name: string; set : S.t} 
    let compare _ _ = 0 
  end 
and S:Set.S = Set.Make (B);;

一切仍然完美无缺。但是,以下模块不正确:

module B2 = 
  struct 
    include B 
    let get_name (x:t) = x.name 
  end;;

返回的错误是“未绑定的记录字段名称”。有什么问题?

1 个答案:

答案 0 :(得分:5)

  

module rec B:Set.OrderedType =

您的递归定义表明模块B具有签名Set.OrderedType,它隐藏了t的定义,在这种情况下,隐藏了其投影。在Set.OrderedType中,类型t是抽象的,如下所示:type t;;

如果要显示类型t的定义,它必须是签名的一部分。第一个示例有效,因为您没有为模块A提供签名,因此默认情况下会使用签名导出所有内容。

以下示例适用于OCaml 4.02.1。

module rec B: 
sig type t = { name:string ; set : S.t } val compare: t -> t -> int end
=
  struct 
    type t = {name: string; set : S.t} 
    let compare _ _ = 0 
  end 
and S:Set.S = Set.Make (B);;

toplevel确认了这个定义:

module rec B :
  sig type t = { name : string; set : S.t; } val compare : t -> t -> int end
and S : Set.S