我試圖將下列遞歸模塊拆分爲單獨的編譯單元。具體來說,我希望B能夠使用它自己的b.ml,以便能夠與其他A一起使用。跨編譯單元的OCaml遞歸模塊
module type AT = sig
type b
type t = Foo of b | Bar
val f : t -> b list
end
module type BT = sig
type a
type t = { aaa: a list; bo: t option }
val g : t -> t list
end
module rec A : (AT with type b = B.t) = struct
type b = B.t
type t = Foo of b | Bar
let f = function Foo b -> [ b ] | Bar -> []
end
and B : (BT with type a = A.t) = struct
type a = A.t
type t = { aaa: a list; bo: t option }
let g b =
let ss = List.flatten (List.map A.f b.aaa) in
match b.bo with
| Some b' -> b' :: ss
| None -> ss
end
let a = A.Bar;;
let b = B.({ aaa = [a]; bo = None });;
let c = A.Foo b;;
let d = B.({ aaa = [a;c]; bo = Some b });;
我不知道如何跨單位拆分它。
從話題澤維爾樂華paper下面的句子給了我希望,它可能使用的OCaml的模塊語法來編碼:「建議不支持編譯單元之間遞歸後者可以但是使用單獨編譯函子來編碼,其後續使用模塊rec結構來確定其固定點「。
我已經玩過模塊rec,但似乎無法找到一種方法來進行類型檢查。在B的函數g中使用A的函數f似乎會造成麻煩。
(關於上下文,在原始代碼中,At是指令類型,Bt是基本塊類型,分支指令引用塊和塊包含指令列表,我想重用基本塊類型和。相關的功能具有不同的指令集)
如果我的回答如下不能解決您與分裂這個文件有問題,請迄今發表您的最好的嘗試在不同的編譯,並且你在'博伽混得'Af'類型錯誤'。 – antron
此外,關注問題的結尾,還有其他方法可以解決此問題 - 例如,在指令中將基本塊索引或鍵存儲到數據結構中,而不是鍵入基本塊參考。 – antron
謝謝antron,在嘗試提出最佳嘗試時,我顯然偶然發現了一個解決方案,至少在這個測試案例中。希望它會翻譯成我的實際代碼。 –