我正在修改用OCaml编写的现有编译器。我已将位置添加到已编译语言的AST中,但这会引起很多错误,因为当相同的AST附加了不同的位置时,以前成功的相等性检查现在会失败。
尤其是,我看到List.mem
在应返回true时返回false,因为它依赖于相等性。
我想知道,对于我的位置类型的任何两个值,我有没有办法指定=
对于此类型的任何两个值始终返回true?
重构整个编译器以在任何地方使用自定义相等性将需要大量工作,特别是由于许多多态函数依赖于能够在任何类型上使用=。
答案 0 :(得分:2)
没有现有的OCaml机制可以执行您想要的操作。
您可以使用ppx编写OCaml语法扩展,并且(据我所知)其行为可能取决于类型。因此,您很有可能会以这种方式工作。但这并没有您想要的那么简单。我怀疑您需要显式处理let leftOrRight: CGFloat = Bool.random() ? 1 : -1
以及任何隐式使用=
的标准函数(如List.mem
)。 (请注意,我没有使用ppx的经验。)
我在这里找到了PPX的描述:http://ocamllabs.io/doc/ppx.html
许多经验丰富的OCaml程序员避免使用内置的多态相等性,因为其行为通常令人惊讶。因此,毕竟值得转换为自定义比较功能。
答案 1 :(得分:1)
有一个烦人的问题。
如果您不顾一切并愿意编写一些C代码,则可以将位置的表示形式更改为Custom_tag
块,从而可以自定义某些多态操作的行为。这是一个令人讨厌的解决方案,我建议您在尝试使用此方法之前会努力寻找一种更好的方法。
一种可能性是大多数编译器根本不使用位置。如果是这样,您也许可以逃脱,用相同的虚拟位置替换AST中的每个位置。那应该允许平等表现得好像根本没有位置一样。这是很棘手的,如果以后在编译器中传递任何位置信息,则可能无法实现。
“干净”的解决方案是为AST定义合理的相等操作(或使用ppx
导出AST)并更改代码以使用该操作。正如您所说,这将需要做更多的工作。