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