处理OCaml中的循环依赖关系

问题描述:

我正在为实验语言编写解释器。该语言的三个主要结构是定义,陈述和表达式。定义可以包含语句和表达式,语句可以包含定义和表达式,一种表达式可以包含语句。我用联合类型来表示所有这些,所以我可以很容易地在它们上使用模式匹配。理想情况下,我想将这些代码放在不同的文件中,但OMake抱怨循环依赖问题。据我所知,跨模块的循环类型定义是不允许的。处理OCaml中的循环依赖关系

我知道的唯一的办法来解决,这是一次定义所有三种类型:

type defn = ... 
and stmt = ... 
and expr = ... 

看起来这需要所有的代码类型是在同一个文件。有没有办法解决?你如何处理你的代码中的循环定义?

递归定义需要出现在同一个文件中。如果要将定义,语句和表达式分隔为单独的模块,则可以使用recursive modules这样做,但它们仍需要出现在同一个文件中。 DAG-ifying文件间依赖性是OCaml的烦恼之一。

这是很容易在它们指的类型参数化的类型解决:

type ('stmt, 'expr) defn = ... 
type ('defn, 'expr) stmt = ... 
type ('defn, 'stmt) expr = ... 

这种技术被称为“解开递归结”(参考难解的结),并在OCaml Journal文章描述。

干杯, Jon Harrop。

另一个常用的解决方案是抽象接口中的类型。由于类型在接口中是抽象的,因此这些接口不是递归依赖的。在实现中,您可以指定类型,并且由于实现仅依赖于接口,所以它们也不是递归的。

唯一的问题是,使用这个解决方案,你不能在它们实现之外的这些类型上进行模式匹配。我个人喜欢将我的程序的所有类型定义在一个模块中(我认为它有助于程序的可读性)。所以,OCaml的这个限制对我来说并不是一个问题。