Types 重新构造2个函子以避免双重实现
(*我想重新表述我之前发布的一个问题,以使其更清晰,吸引更多的关注…我认为这个问题仍然很有趣…*) 我定义了模块类型Types 重新构造2个函子以避免双重实现,types,module,ocaml,functor,Types,Module,Ocaml,Functor,(*我想重新表述我之前发布的一个问题,以使其更清晰,吸引更多的关注…我认为这个问题仍然很有趣…*) 我定义了模块类型区域,如下所示: (* 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 module ZoneC = ZoneFun(PropC) module Zon
区域
,如下所示:
(* 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
module ZoneC = ZoneFun(PropC)
module ZoneA = ZoneFunPrec(PropA)(ZonesmB)
其中i:info
用于包含各种信息,这有助于避免重复计算。它将不总是相同的,因为它取决于构建区域的道具。例如,这里有一个函子,用于从类型为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
(* 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
下面是另一个用于构建类型为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
(* 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
然后我可以按如下方式使用函子:
(* 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
module ZoneC = ZoneFun(PropC)
module ZoneA = ZoneFunPrec(PropA)(ZonesmB)
问题是,type info
和get_prec
(ZoneFun
有它,而zonefunc
没有)是这两个函子的唯一区别;它们的类型prop
和类型t
相同,它们的功能f0
,f1
。。。(有好几个)也完全一样
所以我想知道如何避免两次实现f0
,f1
,等等
有没有人想到重新构造模块/函数来实现这一点并使其具有意义?很抱歉,我没有确切的代码给您,但是您不能将常见函数粘贴到它们自己的模块中,然后包括这样:
module type ZONE =
sig
type info
type prop
type t = { s: string; p: prop; i: info }
include ZoneFunCommon
end
创建一个仅包含共享模式的模块:
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
和zonefunc
的主体中使用此MakeShared
functor来避免代码重复。应该是这样的:
module ZoneFun (Prop : PROP) = struct
type info = { a: int }
type info_ = info
include MakeShared(struct
module Prop = Prop
type info = info_
end)
end
这里需要使用类型别名info\uu
,以避免循环递归类型定义type info=info
。与不是递归的module
不同,因此module Prop=Prop
按预期工作,type
声明始终是递归的
这是重构代码的一种方法。可能还有其他代码,但从伪代码中看不太清楚。例如,您可以在创建实际实例模块的地方,而不是在functor内部使用MakeShared:
module ZoneC = struct
include SmallerZoneFun(PropC)
include MakeShared(...)
end
请尝试尽可能小的问题,并使其可编译。您的代码包含太多对回答者来说毫无意义的细节,不完整,不可编译。分区UNPC(ProcC)是错误的。必须是ZoneFun(ProcC)您关于<代码>ZoneFun(ProcC)
的说法是正确的,刚刚修改。。。