暴露于OCAML中模块扩展的私有类型



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

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定义natext_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中构建本身,因此您没有足够的控制权您的模块,这就是为什么我建议您对代码进行重组(如果不是问题)。

相关内容

  • 没有找到相关文章

最新更新