【问题标题】:How to access a field of a type defined in an OCaml recursive module?如何访问 OCaml 递归模块中定义的类型的字段?
【发布时间】:2015-04-10 17:55:35
【问题描述】:

我正在处理 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;;

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

【问题讨论】:

    标签: recursion types module field ocaml


    【解决方案1】:

    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);;
    

    顶层如此确认定义:

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

    【讨论】:

    • 出于完全相同的原因,我想如果您打算操作非空集,给S 签名Set.S with type elt = B.t 也会很有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    • 2018-07-01
    • 2015-06-10
    • 2012-06-09
    • 1970-01-01
    • 2015-10-25
    相关资源
    最近更新 更多