ReasonML中的流畅接口

时间:2018-12-26 22:49:24

标签: module ocaml functor fluent reason

是否有一种方法可以使用函子模块使模块返回其自身的类型?

示例

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 :(得分:4)

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