重组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
用于包含各种信息,这有助于避免重复计算。它不会总是相同的,因为它取决于构建Zone
的Prop
。举例来说,这里是从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 info
和get_prec
(ZoneFun
有它,而ZoneFunPrec
还没有)是这两个函子的唯一区别;他们的type prop
和type t
是相同的,他们的功能f0
,f1
...(有很多)也是一样的。
所以我想知道如何从执行f0
,f1
避免等两次......
没有人有重组模块/仿函数来实现这一点,并让他们有意义的想法?
创建一个模块只包含共享图案:
module Shared = struct
type prop = Prop.t
type t = { s: string; p: prop; i: info }
let f0 z = "f0"
...
end
我相信在这里你真正f0
较为复杂,取决于你的代码的其他事情。 (否则它可以单独定义在上下文之外)
该模块Shared
由于包含一些免费名称,如Prop
和info
,因此不是真正可编译的。将其更改为一个仿函数,从它的参数取这些名字:
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
。这取决于你省略的代码。
您可以在ZoneFun
和ZoneFunPrec
的主体中使用此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
对不起,我没有给你确切的代码,但不能你坚持的常见功能在自己module
然后include
它想:
module type ZONE =
sig
type info
type prop
type t = { s: string; p: prop; i: info }
include ZoneFunCommon
end
请尝试问题尽可能的小,并使其编译。你的代码包含了太多无意义的细节给答复者,而不是完整的,而且不是可编译的。 ZoneFunPrec(ProcC)是错误的。它必须是ZoneFun(ProcC) – camlspotter
你是对的'ZoneFun(ProcC)',刚刚修改... – SoftTimur