我处于这样一种情况:我正在修改一个用OCaml编写的现有编译器。我已经在编译语言的AST中添加了位置,但它导致了一堆but,因为当相同的AST附加了不同的位置时,以前成功的相等性检查现在会失败。
特别是,我看到List.mem
在应该返回true时返回false,因为它依赖于相等。
我想知道,有没有一种方法可以让我指定,对于我的位置类型的任何两个值,对于这种类型的任何两个值,=
应该始终返回true?
重构整个编译器以在任何地方使用自定义相等将是一项繁重的工作,特别是因为许多多态函数依赖于能够在任何类型上使用=。
发布于 2018-09-05 00:12:13
没有现有的OCaml机制来做你想做的事情。
您可以使用ppx来编写OCaml语法扩展,并且(据我所知)行为可以依赖于类型。所以有一些机会可以让事情以这种方式工作。但它不会像你所要求的那样简单。我怀疑您需要显式处理=
和任何隐式使用=
的标准函数(如List.mem
)。(请注意,我没有使用ppx的经验。)
我在这里找到了对PPX的描述:http://ocamllabs.io/doc/ppx.html
许多有经验的OCaml程序员避免使用内置的多态相等,因为它的行为常常令人惊讶。因此,最终可能值得将其转换为自定义比较函数。
发布于 2018-09-05 07:46:26
这是一个多么烦人的问题啊。
如果你不顾一切并愿意写一些C代码,你可以将位置的表示更改为Custom_tag
块,这允许自定义一些多态操作的行为。这是一个令人讨厌的解决方案,我建议您在求助于此之前努力寻找更好的方法。
一种可能是大多数编译器根本不使用位置。如果是这样的话,您也许能够将AST中的每个位置替换为相同的虚拟位置。这应该允许平等的行为,就像根本不存在位置一样。这是相当复杂的,如果稍后在编译器中传递任何位置信息,则可能是不可能的。
“干净”的解决方案是为AST定义一个合理的相等操作(或使用ppx
派生一个),并更改代码以使用它。正如您所说,这将是更多的工作。
https://stackoverflow.com/questions/52175271
复制相似问题