处理OCaml中的循环依赖关系

时间:2020-03-05 18:45:31  来源:igfitidea点击:

我正在写实验语言的口译员。该语言的三个主要构造是定义,语句和表达式。定义可以包含语句和表达式,语句可以包含定义和表达式,一种表达可以包含语句。我使用联合类型表示所有这些类型,因此我可以轻松地在它们上使用模式匹配。理想情况下,我想将这些代码放在不同的文件中,但是OMake抱怨循环依赖问题。据我所知,不允许在模块之间进行循环类型定义。

我知道解决此问题的唯一方法是一次定义所有三种类型:

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

似乎这要求类型的所有代码都在同一文件中。有没有办法解决?我们如何处理代码中的循环定义?

解决方案

回答

递归定义需要出现在同一文件中。如果要将定义,语句和表达式分成单独的模块,则可以使用递归模块,但它们仍需要出现在同一文件中。 DAG验证文件间依赖关系是OCaml的烦恼之一。

回答

通过将类型参数化为它们所引用的类型,可以轻松解决此问题:

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

此技术称为"消除递归结"(参考Gordian结),并在OCaml Journal文章中进行了描述。

干杯,
乔恩·哈罗普。