在OCaml中公开模块扩展的私有类型

时间:2017-09-01 11:03:36

标签: module ocaml encapsulation inclusion

我想扩展模块,但我需要访问其私有组件。这是一个例子:

nat.mli:
type t 
val zero : t
val succ : t -> t

nat.ml:
type t = int
let zero = 0
let succ x = x + 1

我想定义一个定义Ext_nat函数的新模块double。我试图做这样的事情。

ext_nat.mli:
include (module type of Nat)
val double : t -> t

ext_nat.ml:
include Nat
let double x = 2 * x

它没有工作,因为我无法访问最后一行中x的代表。

现在我正在思考这个问题,无论如何这可能不是一个好主意,因为这会破坏nat的封装。那么最好的方法是什么?我可以在签名中定义nat_public其中type t = int的新模块,并使用私有nat定义ext_nattype t。你觉得怎么样?

1 个答案:

答案 0 :(得分:1)

您需要使用with type声明。可以用许多不同的方式编写下面的代码,但这个想法总是一样的。

module type NatSig =
  sig
    type t
    val zero : t
    val succ : t -> t
  end

module type ExtNatSig =
  sig
    include NatSig
    val double : t -> t
  end

module ExtNat : ExtNatSig =
  struct
    type t = int
    let zero = 0
    let succ = fun x -> x + 1
    let double = fun x -> x * 2
  end

module Nat = (ExtNat : NatSig with type t = ExtNat.t)

let z = Nat.zero
let _ = ExtNat.double z

问题在于,据我所知,使用您的文件结构无法实现此行为:您使用.mli文件中的签名隐式定义模块,并在.ml中构造自身,因此您无法控制你模块,这就是为什么我建议你稍微重新组织你的代码(如果这不是问题)。