1

(* 我想重新表述我之前发布的一个问题,以使其更清晰并引起更多关注......我认为这个问题仍然很有趣...... *)

我定义了一个模块类型ZONE如下:

(* part of zone.ml *)
module type ZONE =
sig
  type info
  type prop
  type t = { s: string; p: prop; i: info }
  val f1 : t -> string
end

wherei: info用于包含各种信息,有助于避免重复计算。它不会总是相同的,因为它取决于构建Propa的源。Zone例如,这是一个函子,用于从 type 的模块构建ZonetypeZONE的模块PROP,具有基本的info

(* part of zone.ml *)
module ZoneFun (Prop : PROP) = struct
  type info = { a: int }
  type prop = Prop.t
  type t = { s: string; p: prop; i: info }
  let f0 z = "f0"
  ...
end

这是另一个构建Zone类型模块的函子ZONE,相对更复杂info

(* zoneFunPrec.ml *)
module ZoneFunPrec (Prop: PROP) (Prec: ZONESM) = struct
  type info = { a: int; b: Prec.t }
  type prop = Prop.t
  type t = { s: string; p: prop; i: info }
  let get_prec z = z.info.prec
  let f0 z = "f0"
  ...
end   

然后我可以按如下方式使用函子:

module ZoneC = ZoneFun(PropC)
module ZoneA = ZoneFunPrec(PropA)(ZonesmB)

问题是,type infoget_prec(ZoneFun有它,而ZoneFunPrec没有) 是这两个函子的唯一区别;它们的type proptype t是相同的,它们的功能f0f1...(有很多)也完全一样。

所以我想知道如何避免两次实施f0,f1等......

有没有人有重组模块/函子以实现这一目标并使它们有意义的想法?

4

2 回答 2

0

抱歉,我没有适合您的确切代码,但是您不能将常用功能粘贴在自己的代码中module,然后include就像:

module type ZONE =
sig
  type info
  type prop
  type t = { s: string; p: prop; i: info }
  include ZoneFunCommon
end
于 2013-09-24T18:13:36.130 回答
0

创建一个仅包含共享模式的模块:

module Shared = struct
  type prop = Prop.t
  type t = { s: string; p: prop; i: info }
  let f0 z = "f0"
  ...
end

我相信这里你的真实f0更复杂,并且取决于你代码中的其他东西。(否则它可以在上下文之外单独定义。)

该模块Shared不是真正可编译的,因为它包含一些自由名称,例如Propinfo。将其更改为从其参数中获取这些名称的仿函数:

module MakeShared(A : sig
  module Prop : sig
    type t
  end
  type info
end) = struct
  type prop = Prop.t
  type t = { s : string; p : prop; i : info }
  let f0 z = "f0"
  ...
end

您可能需要在签名中添加更多内容A。这取决于您省略的代码。

您可以在和MakeShared的主体中使用此函子来避免代码重复。它应该是这样的:ZoneFunZoneFunPrec

module ZoneFun (Prop : PROP) = struct
  type info = { a: int }
  type info_ = info
  include MakeShared(struct
    module Prop = Prop
    type info = info_
  end)
end

这里需要类型别名info_以避免循环 recusvie 类型定义type info = info。不像modulewhich 不是递归的,因此module Prop = Prop可以按预期工作,type声明总是递归的。

这是重构代码的一种方法。可能还有其他人,但从您的伪代码中不是很清楚。例如,您可以不在仿函数内部使用 MakeShared,而是在创建实际实例模块的地方使用:

module ZoneC = struct
  include SmallerZoneFun(PropC)
  include MakeShared(...)
end
于 2013-09-25T11:00:57.390 回答