2012-01-30 50 views
7

我知道可以定义递归模块,是否有人知道如何定义递归签名?例如,我想知道:定义模块的递归签名

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 

任何人都可以帮忙吗?

回答

6

你不能,据我可以告诉。最接近的解决方案是限制“递归”位,实际需要的表达单独每个签名:当你定义模块

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 
+0

感谢您的答案......最接近的解决方案是限制“递归”位==>请您详细说明解决方案的局限性吗? – SoftTimur 2012-01-31 13:42:01

+1

好吧,这不允许你表示签名之间的任意递归,因为你需要能够将每个签名的自包含子集作为一种前向声明来分离。此外,你在两个地方重复每个子集 - 但是命名和包含它们可以在那里帮助。在我的回答中,我没有打算这么做,因为相关的子集(类型t)足够小。 – 2012-01-31 15:25:50

4

你可以写这样的事情:

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 
+0

感谢您的评论,但我真的想给签名的名字,例如,'AAA' aor'BBB' ...你没有在你的答案中提及... – SoftTimur 2012-01-30 13:30:26