这个问题类似于这一个,但我想声明一个递归的functor而不是递归的module。所以我有:
一个实现了
一个接口A
:
module type A = sig
type t
val basic_func: ...
val complex_func: ...
end
一个实现了
A.complex_func
的函数对象 ComplexImpl
,其基于 A.basic_func
实现:module ComplexImpl (SomeA : A) =
struct
let complex_impl params =
SomeA.basic_func ...
...
end
另一个接口I
:
module type I = sig
type t
...
end
还有一个函数对象B
,它接受类型为I
的参数,实现接口A
并使用ComplexImpl
来实现complex_func
。我想写出这样的代码:
(* I can't write 'rec' here *)
module rec B (SomeI : I) :
A with type t = SomeI.t
= struct
type t = SomeI.t
(* this line does not work *)
module Impl = ComplexImpl(B(I))
let basic_func (x : t) = ...
let complex_func (x : t) =
Impl.complex_impl x
end
但是我无法声明一个递归函数对象...
我找到的实现递归函数对象的唯一方法是将它自己作为参数:
module B (SomeI : I) (CopyOfB : A with type t = SomeI.t) :
A with type t = SomeI.t
= struct
type t = SomeI.t
(* this line works *)
module Impl = ComplexImpl(CopyOfB)
let basic_func (x : t) = ...
let complex_func (x : t) =
Impl.complex_impl x
end
然后像这样使用:
module rec RealB = B(SomeI)(RealB)
但是语法冗长,不太安全(如果有人输入与RealB
不同的参数会怎样),如果RealB
本身是一个函数符号,则变得非常棘手...
B(SomeI)
的签名是A with type t = SomeI.t
。因此,按照您的术语,Name
的module_type
取决于Arg
,这是无效的(除非我漏掉了什么)。 - SteakflyName
的module_type
也将采用functor (Arg : modtype) -> modtype
的形式(因为Name
的类型是一个函数子类型)。我会更新我的答案以使其更清晰明了。 - Leo White无法安全地评估递归定义模块B的定义
。 - Steakfly