簡體   English   中英

OCaml中的遞歸函子

[英]Recursive functor in OCaml

這個問題類似於這一個 ,但我要聲明一個遞歸函數對象,而不是遞歸模塊。 所以我有 :

界面A

module type A = sig
    type t
    val basic_func: ...
    val complex_func: ...
end

一個A.complex_func函數ComplexImpl ,它根據A.basic_func實現A.basic_func

module ComplexImpl (SomeA : A) =
struct
    let complex_impl params =
        SomeA.basic_func ...
        ...
end

另一個界面I

module type I = sig
    type t
    ...
end

並且接受類型I的參數的仿函數B實現接口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本身就是一個RealB函數,那就變得非常棘手......

我找到了一個解決方案:

module B (SomeI : I) = struct
    (* introduce a recursive module Implementation *)
    module rec Implementation :
        A with type t = SomeI.t
    = struct
        type t = SomeI.t
        (* use Implementation here *)
        module Impl = ComplexImpl(Implementation)

        let basic_func (x : t) = ...
        let complex_func (x : t) =
            Impl.complex_impl x
    end

    (* include the code of Implementation here *)
    include Implementation
end

我可以像這樣使用它:

module RealB = B(SomeI)

遞歸模塊具有以下形式的語法限制:

module rec Name : module_type = module_expr

這意味着無法使用以下方式聲明遞歸仿函數:

module rec Name (Arg : module_type) : module_type = module_expr

但必須寫成:

module rec Name : functor (Arg : module_type) -> module_type =
  functor (Arg : module_type) -> module_expr

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM