ReasonML 中的流畅界面

Fluent Interface in ReasonML

有没有办法使用仿函数子模块让模块return自己的类型?

例子

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 中,return 是它自己的类型,所以它看起来像

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 中可行吗?

谢谢

不,这是不可能的。您的模块类型 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 模块列表的组合器,但我想知道这在实践中会有多大用处。