【问题标题】:Define recursive signatures for modules为模块定义递归签名
【发布时间】:2012-01-30 02:10:27
【问题描述】:

我知道可以定义递归模块,有人知道如何定义递归签名吗?例如,我想实现:

module type AAA = sig
  module Bbb : BBB
  type 'a t 
  val f : 'a Bbb.t -> 'a t
end

module type BBB = sig
  module Aaa : AAA
  type 'a t 
  val g : 'a Aaa.t -> 'a t
end

有人可以帮忙吗?

【问题讨论】:

    标签: types module ocaml signature


    【解决方案1】:

    据我所知,你不能。最接近的解决方案是将“递归”位限制为分别表示每个签名实际需要的位:

    module type AA =
    sig
      module B : sig type t end
      type t
      val f : unit -> B.t
    end
    
    module type BB =
    sig
      module A : sig type t end
      type t
      val g : unit -> A.t
    end
    

    然后在定义模块时进行细化:

    module rec A : AA with module B = B =
    struct
      module B = B
      type t = int
      let f () = B.g ()
    end
    and B : BB with module A = A =
    struct
      module A = A
      type t = int
      let g () = A.f ()
    end
    

    FWIW,有人可能认为应该可以通过使用递归模块来表达递归签名(有很多重复):

    module rec AA :
    sig
      module type T = sig module B : BB.T end
    end =
    struct
      module type T = sig module B : BB.T end
    end
    and BB :
    sig
      module type T = sig module A : AA.T end
    end =
    struct
      module type T = sig module A : AA.T end
    end
    

    但是,这不起作用:

    Error: Unbound module type BB.T
    

    【讨论】:

    • 感谢您的回答...the closest solution is to limit the "recursive" bits ==>您能否详细说明您的解决方案的局限性?
    • 好吧,这不允许您在签名之间表达任意递归,因为您需要能够将每个签名的自包含子集隔离为一种前向声明。此外,您在两个地方重复这些子集中的每一个——但命名和include-ing 它们可以在那里提供帮助。在我的回复中,我没有费心去做,因为相关的子集(类型 t)足够小。
    【解决方案2】:

    你可以这样写:

    module rec Aaa : sig
      type 'a t 
      val f : 'a Bbb.t -> 'a t
    end = Aaa
    and Bbb : sig
      type 'a t
      val g : 'a Aaa.t -> 'a t
    end = Bbb
    

    【讨论】:

    • 感谢您的评论,但我真的很想为签名命名,例如,AAA aor BBB...您在回答中没有提到...
    猜你喜欢
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 2016-06-09
    • 2018-07-02
    • 1970-01-01
    • 2020-07-11
    • 2021-09-06
    相关资源
    最近更新 更多