我已经构建了几个模块,包括匹配模块类型EEA
的{{1}}。现在我想构建2个仿函数,如下所示:
PROP
因此,仿函数允许我构建模块:
(* zone.ml *)
module type ZONE =
sig
...
end
module ZoneFun (Prop : PROP) = struct
type t =
{ i: int;
pal: ZonesEEA.t }
...
end
(* zones.ml *)
module ZonesFun (Zone: ZONE) = struct
type t = Zone.t list
...
end
但是,代码不起作用,因为有一个递归:(* modules.ml *)
open EEA
open Zone
open Zones
module ZoneEEA = ZoneFun(EEA)
module ZonesEEA = ZonesFun(ZoneEEA)
需要ZoneFun
,它来自ZonesEEA.t
,因此ZoneEEA
...
有没有人有想法重构代码来实现这种递归?
答案 0 :(得分:0)
您需要跨模块进行某种递归。这会产生循环依赖,并且不能像OCaml那样完成。但是,如果您可以在pal
中抽象ZoneFun
的类型,那么您可以做到这一点。我正在向ZoneFun
仿函数添加一个参数,从中将pal
类型。我正在调用此参数Z
,我将其类型为ZONES
,因为它稍后将使用ZonesEEA
进行实例化。
(* zone.ml *)
module type ZONES = sig
type t
...
end
module ZoneFun (Prop : PROP) (Z : ZONES) = struct
type t =
{ i: int;
pal: Z.t }
...
end
然后,ZoneEEA
和ZonesEEA
将是相互递归的模块:
(* modules.ml *)
open EEA
open Zone
open Zones
module rec ZoneEEA : ZONE = ZoneFun(EEA)(ZonesEEA)
and ZonesEEA : ZONES = ZonesFun(ZoneEEA)