【发布时间】:2016-02-02 10:59:31
【问题描述】:
我正在尝试将以下递归模块拆分为单独的编译单元。具体来说,我希望 B 在自己的 b.ml 中,以便能够与其他 A 重用它。
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 });;
我不知道如何跨单元拆分它。
来自 Xavier Leroy 的 paper 关于该主题的以下句子让我希望可以使用 OCaml 的模块语法进行编码:“该提案不支持编译单元之间的递归。但是后者可以使用单独编译的仿函数进行编码,其固定点稍后会使用模块 rec 构造”。
我玩过模块 rec,但似乎无法找到一种方法来对其进行类型检查。在 B 的函数 g 中使用 A 的函数 f 似乎会造成麻烦。
(对于上下文,在原始代码中At是指令类型,Bt是基本块类型。分支指令引用块,块包含指令列表。我想重用基本块类型和关联具有不同指令集的函数。)
【问题讨论】:
-
如果我下面的回答不能解决您在拆分此文件时遇到的问题,请在单独编译时发布您迄今为止的最佳尝试,以及您在
A.f中遇到的类型错误B.g. -
另外,关注你问题的结尾,还有一些其他方法可以解决这个问题——例如,将基本块索引或键存储到数据结构中,而不是键入基本块引用,在您的指示。
-
谢谢antron,在尝试做出最佳尝试时,我显然偶然发现了一个解决方案,至少对于这个测试用例是这样。希望它能转化为我的实际代码。
-
好,祝你好运:)
标签: recursion module ocaml functor