我用模块构建了一个复杂的结构,里面有一个递归。编译给了我一个我无法解决的错误(虽然我不认为它真的是由于递归)。有人可以帮忙吗?
首先,定义了接口ZONE
和仿函数ZoneFunPrec
:
(* zone.ml *)
module type ZONE = sig
type prop
type info
type t
end
(* zoneFunPrec.ml *)
open Prop
open Zonesm
module ZoneFunPrec (Prop : PROP)(Prec: ZONESM with type prop = Prop.t) = struct
type prop = Prop.t
type info = { mark: int option; prec: Prec.t option }
type t = { prop: prop; info: info }
end
仿函数ZonesFun
和接口ZONES
,其元素是具有相同属性的区域列表:
(* zones.ml *)
open Prop
open Zone
module type ZONES = sig
type prop
type zone
type t
end
module ZonesFun (Prop: PROP) (Zone: ZONE with type prop = Prop.t) = struct
type prop = Prop.t
type zone = Zone.t
type t = | ZSbot | ZS of zone list
end
仿函数ZonesmFun
和界面ZONESM
,其元素是从String
到具有相同属性的ZONES
的地图:
(* zonesm.ml *)
open Prop
open Zone
open Zones
module SMap = Map.Make(String)
module type ZONESM = sig
type prop
type zones
type t
end
module ZonesmFun (Prop: PROP)
(Zone: ZONE with type prop = Prop.t)
(Zones: ZONES with type zone = Zone.t) = struct
type prop = Prop.t
type zones = Zones.t
type t = | Bot | ZSM of Zones.t SMap.t
end
然后,我尝试从EEA
构建一些模块,其接口为PROP
:
(* modules.ml *)
open E_expression_abs
open Zone
open ZoneFunPrec
open Zones
open Zonesm
module EEA = E_expression_abs
module rec ZoneEEA : ZONE = ZoneFunPrec(EEA)(ZonesmEEA)
and ZonesEEA : ZONES = ZonesFun(EEA)(ZoneEEA)
and ZonesmEEA : ZONESM = ZonesmFun(EEA)(ZoneEEA)(ZonesEEA)
在我的makefile
中,编译顺序与我列出上述文件的顺序相同。然后编译器在行module rec...
中给出了一个错误:
File "domains/modules.ml", line 7, characters 45-54:
Error: Signature mismatch:
Modules do not match:
sig
type prop = ZonesmEEA.prop
type zones = ZonesmEEA.zones
type t = ZonesmEEA.t
end
is not included in
sig type prop = EEA.t type zones type t end
Type declarations do not match:
type prop = ZonesmEEA.prop
is not included in
type prop = EEA.t
显然,编译器无法知道ZonesEEA.prop
实际上是EEA.t
......
答案 0 :(得分:0)
我不擅长递归模块输入,但是...我想你的例子简化为以下
module type S = sig type t end
module rec R : S = (R : S with type t = int)
由于签名不匹配,OCaml拒绝此代码。这是因为R在等式的左手和右手中具有不兼容的类型。你必须说:
module rec R : S with type t = int = (R : S with type t = int)
R必须在双手中具有相同的模块类型,因为R是递归定义的。
如果不是递归,你可以说:
module M = struct type t = int end
module N : S = (M : S with type t = int)
等式左边的模块类型可能比右边的模块类型更抽象。