我可以用 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);
};

有没有办法在两种模块类型之间共享抽象类型 ttoken? 我试过了:

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