是否有一种方法可以使用函子模块使模块返回其自身的类型?
示例
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?
谢谢
答案 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
模块列表的组合器,尽管我想知道这在实践中将多么有用。