我想扩展一个模块,但我需要访问其私有组件。这是一个例子:
nat.mli:
type t
val zero : t
val succ : t -> t
nat.ml:
type t = int
let zero = 0
let succ x = x + 1
我想定义一个定义double
函数的新模块Ext_nat
。我试图做这样的事情。
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
,并使用私有type t
定义nat
和ext_nat
。你怎么看?
您需要使用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中构建本身,因此您没有足够的控制权您的模块,这就是为什么我建议您对代码进行重组(如果不是问题)。