我试图将下列递归模块拆分为单独的编译单元。具体来说,我希望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,在尝试提出最佳尝试时,我显然偶然发现了一个解决方案,至少在这个测试案例中。希望它会翻译成我的实际代码。 –