我可以用 1 个模块实现多种模块类型吗?
Can I implement multiple module types with 1 module?
鉴于这些模块类型:
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;
}
但是编译器抱怨名称冲突。
确实可以,使用 signature constraints with destructive substitution:
module type Codec = {
include Encode;
include Decode with type t := t and type token := token;
}
请注意,您也可以使用 =
而不是 :=
来编写签名约束,但这会产生相同的错误。它们的区别在于=
是类型相等,要求两边的类型相等,而:=
会替换("destructively substitute")左边的类型。在这种情况下,这意味着 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
。
鉴于这些模块类型:
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;
}
但是编译器抱怨名称冲突。
确实可以,使用 signature constraints with destructive substitution:
module type Codec = {
include Encode;
include Decode with type t := t and type token := token;
}
请注意,您也可以使用 =
而不是 :=
来编写签名约束,但这会产生相同的错误。它们的区别在于=
是类型相等,要求两边的类型相等,而:=
会替换("destructively substitute")左边的类型。在这种情况下,这意味着 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
。