处理OCaml中的循环依赖关系

处理OCaml中的循环依赖关系

Dealing with circular dependencies in OCaml

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

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

1
2
3
type defn = ...
and stmt = ...
and expr = ...

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


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


通过在您所引用的类型上对其类型进行参数化,可以轻松解决此问题:

1
2
3
type ('stmt, 'expr) defn = ...
type ('defn, 'expr) stmt = ...
type ('defn, 'stmt) expr = ...

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

干杯,
乔恩·哈罗普。


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

唯一的问题是,使用此解决方案,您将无法再在其实现之外对这些类型进行模式匹配。

就个人而言,但这可能只是一个口味问题,我喜欢在一个模块中定义所有类型的程序(我认为这有助于提高程序的可读性)。因此,对OCaml的限制对我来说并不是真正的问题。


推荐阅读

    linux改语言命令行?

    linux改语言命令行?,系统,环境,工具,密码,概念,地方,软件,通信,管理,国际,lin

    linux循环复制命令?

    linux循环复制命令?,系统,文件,命令,目录,地址,源文件,文件夹,目标,文件名,

    linux编写c语言命令?

    linux编写c语言命令?,系统,基础,环境,代码,盘面,保险,百度,情况,数据,工具,在

    linux命令行写循环?

    linux命令行写循环?,工作,系统,地址,命令,情况,定期,基础,连续,信息,文件,Lin

    linux循环命令脚本?

    linux循环命令脚本?,代码,系统,增长,工具,官网,项目,流程,数据,数字,底部,lin

    linux跳出死循环命令?

    linux跳出死循环命令?,系统,地址,数字,代码,官方网站,网络,工作,工具,信息,

    linux循环语句命令?

    linux循环语句命令?,地方,增长,数字,语句,流程,名称,工具,代码,数据,条件,Lin

    linux命令正则表达式?

    linux命令正则表达式?,工作,环境,基础,网络,单位,名称,平台,信息,正规,管理,L

    dolinux循环命令?

    dolinux循环命令?,系统,工具,时间,信息,增长,代码,对比,数字,官网,定期,如何

    linux改变语言命令?

    linux改变语言命令?,系统,管理,网上,官方网站,情况,服务,中文,语言,命令,终

    c语言编译linux命令?

    c语言编译linux命令?,代码,工具,环境,系统,基础,保险,百度,语言,源程序,文件

    linux常用命令语言?

    linux常用命令语言?,工作,地址,系统,信息,命令,目录,标准,管理,工具,服务,lin

    r语言命令行写linux?

    r语言命令行写linux?,环境,数据,系统,工具,简介,官网,语言,报告,软件,发展,如

    嵌入式linux命令语句?

    嵌入式linux命令语句?,系统,环境,基础,网络,软件,基础知识,服务,设备,管理,

    linux语言查找命令行?

    linux语言查找命令行?,系统,工作,位置,标准,地址,信息,命令,管理,时间,文件,

    Python编程语言特征

    Python编程语言特征,代码,异常,环境,管理,培训,标准,检测,网络,特征,模块,1