Свободный интерфейс в ReasonML - PullRequest
0 голосов
/ 27 декабря 2018

Есть ли способ заставить модуль возвращать свой собственный тип, используя подмодуль функтора?

Пример

module type A = {};
module type B = { let varB: int; };

module AMod : A = {};
module BMod : B = { let varB = 42; };

module Fn = (A: A, B: B) => A; /* Lets say this does some complex function that returns Type A */
module A2 = Fn(AMod, BMod);

Мне нужен интерфейс Fluent, в котором функтор будетA, который возвращает свой собственный тип, чтобы он выглядел как

module type C = { module Fn: (B) => C };
module CMod : C = { Fn: (B) => C};

module C2 = CMod.Fn(BMod).Fn(BMod).Fn(BMod).Fn(BMod).Fn(BMod);

Возможно ли это в Reason или Ocaml?

Спасибо

1 Ответ

0 голосов
/ 27 декабря 2018

Нет, это невозможно.Ваш тип модуля C будет рекурсивным, что недопустимо.Такая форма рекурсии может очень легко привести к неразрешимой проверке типов, учитывая выразительную силу типов модулей.

Кажется, что вы пытаетесь вставить объектно-ориентированный шаблон в модули, которые обычно не работают- Модули ML очень функциональны по своей природе.Что не так со следующим?

module A2 = Fn(Fn(Fn(Fn(Fn(A, B), B), B), B), B)

Если вы заинтересованы в сокращении общего паттерна, вы можете реализовать комбинатор модулей (в простом Ocaml, поскольку я недостаточно хорошо знаю синтаксис Reason):

module type FN = functor (X:A)(Y:B) -> A
let rec fn n =
  if n = 0 then (module (functor (X:A)(Y:B) -> X) : FN)
  else (module (functor (X:A)(Y:B) -> (val fn (n-1))(X)(Y)))

module A2 = (val fn 5)(AMod)(BMod)

Вы также можете написать комбинаторы, которые берут список различных B модулей, хотя мне интересно, насколько это полезно на практике.

...