给出以下模块类型:
module type CodecTypes = {
type t;
type token;
};
module type Decode = {
include CodecTypes;
let decode: BsGenericParser.Parse.parser(token, t);
};
module type Encode = {
include CodecTypes;
let encode: t => list(token);
};
是否可以在两种模块类型之间共享抽象类型t
和token
?
我尝试过:
module type Codec = {
include Encode;
include Decode;
}
但是编译器抱怨名称冲突。
答案 0 :(得分:3)
实际上可以将signature constraints与destructive substitution结合使用:
module type Codec = {
include Encode;
include Decode with type t := t and type token := token;
}
请注意,您也可以使用=
而不是:=
来编写签名约束,但这会产生相同的错误。它们之间的区别在于=
是一个类型相等,要求两侧的类型都相等,而:=
将替换(“破坏性替换”)左侧的类型。在这种情况下,这意味着将Decode.t
替换为Encode.t
。
为了更好地说明这一点,请考虑以下示例:
module type Codec = {
type u;
include Encode with type t := u;
include Decode with type t := u and type token := token;
}
这将导致以下模块类型:
module type Codec = {
type u;
type token;
let encode: u => list(token);
let decode: list(token) => u;
};
t
根本不再出现,取而代之的是u
。