Могу ли я реализовать несколько типов модулей с 1 модулем? - PullRequest
3 голосов
/ 19 апреля 2020

Учитывая следующие типы модулей:

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

, но компилятор жалуется на конфликт имен.

1 Ответ

3 голосов
/ 19 апреля 2020

Действительно, вы можете, используя ограничения подписи с деструктивным замещением :

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.

...