3

Given these module types:

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);
};

Is there a way to share the abstract types t and token between the two module types? I tried:

module type Codec = {
  include Encode;
  include Decode;
}

but the compiler complains about name clashes.

glennsl
  • 28,186
  • 12
  • 57
  • 75
Felix
  • 8,385
  • 10
  • 40
  • 59

1 Answers1

3

Indeed you can, using signature constraints with destructive substitution:

module type Codec = {
  include Encode;
  include Decode with type t := t and type token := token;
}

Note that you can also write signature constraints with = instead of:=, but this will yield the same error. The difference between them is that = is a type equality that require the type on both sides to be equal, and := will replace ("destructively substitute") the type on the left-hand side. In this case that means Decode.t is replaced by Encode.t.

To better illustrate this, consider this example:

module type Codec = {
  type u;
  include Encode with type t := u;
  include Decode with type t := u and type token := token;
}

which will result in the following module type:

module type Codec = {
  type u;
  type token;
  let encode: u => list(token);
  let decode: list(token) => u;
};

where t no longer occurs at all, having been replaced by u instead.

glennsl
  • 28,186
  • 12
  • 57
  • 75
  • I have no idea. See the note I just added at the end. I'm hoping our resident documentation guru will either know where it is and/or fix it if necessary. – glennsl Apr 19 '20 at 15:01
  • Well. At least it’s documented _here_ now . Thanks! – Felix Apr 19 '20 at 15:07
  • Like often, if this is not documented in the technical reference part of the manual, this means that the documentation is in the extension chapter: https://ocaml.org/releases/4.10/htmlman/signaturesubstitution.html . – octachron Apr 19 '20 at 15:12
  • Thanks @octachron. That's a good explanation too. I think one reason it's hard to find is that it uses the term "signature constraint", while the core language calls it a "module constraint" (although it also mentions "constrained signature"). This makes it more difficult to find through search. – glennsl Apr 19 '20 at 15:51
  • Would be nice to have the ocaml manual completely translated into Reason for those who never touched ocaml before. – Felix Apr 19 '20 at 17:19