如何在嵌套模块签名中使用同名类型?

Val*_*nko 1 ocaml name-conflict

通常的做法是将模块中的主要类型命名为“t”。我可以在结构级别解决嵌套模块和容器模块之间的类型名称冲突,如下所示:

module Container = struct
  type t = A | B
  
  module Nested = struct
    type container_t = t
    type t = C | D

    let f = function
      | A -> C
      | B -> D
  end
end
Run Code Online (Sandbox Code Playgroud)

另外,我可以在签名级别执行相同的技巧:

module type CONTAINER = sig
  type t = A | B
  
  module Nested : sig
    type container_t = t
    type t = C | D

    val f : container_t -> t
  end
end
Run Code Online (Sandbox Code Playgroud)

“container_t”帮助我解决了冲突,但我不需要让它保持可见。有什么办法可以隐藏它吗?如何在嵌套模块签名中使用“CONTAINER.t”和“Nested.t”进行操作而不产生冗余类型?

oct*_*ron 5

OCaml 4.08 中引入了本地替换来解决此问题。写作,

  type container_t := t
Run Code Online (Sandbox Code Playgroud)

将引入类型 t 的本地名称container_t,该名称不会成为模块(外部)签名的一部分。例如,

  module Nested : sig
    type container_t := t
    type t = C | D
    val f : container_t -> t
  end
  val u: Nested.container_t
Run Code Online (Sandbox Code Playgroud)

失败了

错误:未绑定类型构造函数 Nested.container_t