我已經和特別是通過MyFunctor
定義的接口A
由幾個仿函數可以使用:相互遞歸模塊和函子OCaml中
module type A = sig
val basic_func: ...
val complex_func: ...
end
module MyFunctor :
functor (SomeA : A) ->
struct
...
let complex_impl params =
...
(* Here I call 'basic_func' from SomeA *)
SomeA.basic_func ...
...
end
現在我要定義一個模塊B
與實現接口A
。特別是,complex_func
實施應在MyFunctor
使用basic_func
通過complex_impl
:
module B = struct
let basic_func = ...
let complex_func ... =
let module Impl = MyFunctor(B) in
Impl.complex_impl ...
end
但是,此代碼不能編譯爲B
不完全的MyFunctor(B)
的上下文中聲明。很顯然B
取決於MyFunctor(B)
,這本身取決於B
,所以我試圖在模塊B
上使用rec
關鍵字,但它沒有解決。
那麼,是否有可能做這樣的事情?這將是有用的,因爲我有幾個模塊B_1, ..., B_n
使用相同的實現B_k.complex_func
根據B_k.basic_func
。
或者我的問題有更好的模式嗎?我知道我可以聲明complex_impl
作爲常規函數以basic_func
作爲一個參數,而無需使用仿函數都:
let complex_impl basic_func params =
...
basic_func ...
...
但在我的情況下complex_impl
使用的A
許多基本功能,我認爲範式函子更清晰,更不容易出錯。
編輯:我跟着this answer,但事實上,A
使用某種類型的t
是一家專業從事B
:
module type A = sig
type t
val basic_func: t -> unit
val complex_func: t -> unit
end
module MyFunctor :
functor (SomeA : A) ->
struct
let complex_impl (x : SomeA.t) =
SomeA.basic_func x
...
end
module rec B : A = struct
type t = int
val basic_func (x : t) = ...
val complex_func (x : t) =
let module Impl = MyFunctor(B) in
Impl.complex_impl x
end
現在我得到的錯誤(x
在行Impl.complex_impl x
):
This expression has type t = int but an expression was expected of type B.t
編輯2:我解決了第二個問題,下面的代碼:
module rec B :
A with type t = int
= struct
type t = int
...
end
謝謝您的回答,我寫了'模塊REC B = struct',錯過了'B:A'一部分。 – Steakfly 2015-02-24 13:13:44
但是,我仍然有錯誤(請參閱我的編輯)... – Steakfly 2015-02-24 13:50:48