重组2个仿函数,以避免重复执行

问题描述:

(*我想重新制定,我以前张贴的问题,以使其更清晰,并吸引了更多的关注。我认为这个问题仍然是有趣。*)重组2个仿函数,以避免重复执行

我已经定义了一个模块式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 

其中i: info用于包含各种信息,这有助于避免重复计算。它不会总是相同的,因为它取决于构建ZoneProp。举例来说,这里是从PROP类型的模块构建ZONE类型的模块Zone一个仿函数,一个基本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_precZoneFun有它,而ZoneFunPrec还没有)是这两个函子的唯一区别;他们的type proptype t是相同的,他们的功能f0,f1 ...(有很多)也是一样的。

所以我想知道如何从执行f0f1避免等两次......

没有人有重组模块/仿函数来实现这一点,并让他们有意义的想法?

+1

请尝试问题尽可能的小,并使其编译。你的代码包含了太多无意义的细节给答复者,而不是完整的,而且不是可编译的。 ZoneFunPrec(ProcC)是错误的。它必须是ZoneFun(ProcC) – camlspotter

+0

你是对的'ZoneFun(ProcC)',刚刚修改... – SoftTimur

创建一个模块只包含共享图案:

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。这取决于你省略的代码。

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

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。不像module这是不递归的,因此module Prop = Prop按预期工作,type声明总是递归的。

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

module ZoneC = struct 
    include SmallerZoneFun(PropC) 
    include MakeShared(...) 
end 
+0

谢谢...会让你知道它是否合适... – SoftTimur

+0

这样的作品,谢谢你... – SoftTimur

对不起,我没有给你确切的代码,但不能你坚持的常见功能在自己module然后include它想:

module type ZONE = 
sig 
    type info 
    type prop 
    type t = { s: string; p: prop; i: info } 
    include ZoneFunCommon 
end