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

Module 在OCaml中公开模块扩展的私有类型,module,ocaml,encapsulation,inclusion,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\u nat,它定义了一个double函数。我试着做这样的事情 ext_nat.mli: include (module type of Nat) val double : t -> t ext

我想扩展一个模块,但我需要访问它的私有组件。下面是一个例子:

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\u 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\u public
,其中
type t=int
,并使用私有
type t
定义
nat
ext\u nat
。您觉得怎么样?

您需要将
与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中使用结构本身,因此您对模块没有足够的控制权,这就是为什么我建议您稍微重新组织代码(如果没有问题的话)