2012-01-30 74 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