Haskell 支持相互递归的 let 绑定,这很棒。 Haskell 不支持相互递归模块,这有时很糟糕。我知道 GHC 有 其
.hs-boot
机制,但我认为这有点像黑客。
据我所知,对相互递归模块的透明支持应该相对“简单”,并且可以像相互递归的let绑定一样完全完成:而不是将每个单独的模块作为编译单元,我会将每个模块依赖图的强连接组件作为编译单元。
我在这里遗漏了什么吗? Haskell 不以这种方式支持相互递归模块有什么重要的原因吗?
这个 6 年前的功能请求票 包含大量的讨论,您可能已经看到了。其要点是,就 GHC 而言,这并不完全是一个简单的更改。提出了一些具体问题:
GHC 目前对编译期间如何处理模块有很多固有的假设,并且显着改变这些假设将远远超过对相互递归模块的透明支持的好处。
将模块组集中在一起意味着它们必须一起编译,这意味着生成单独的
.hi
和 .o
文件需要更多的重新编译和尴尬。向后兼容使用
hs-boot
文件的现有版本。您有可能在相互递归模块组中进行跨模块边界的相互递归绑定,这会引发涉及隐式模块级范围(例如默认和可能的类型类实例)的任何问题。
当然,还有可能出现未知的、未预料到的错误,就像任何改变 GHC 中长期存在的假设的事情一样。即使不对编译过程进行大规模更改,目前也假设许多内容是在每个模块的基础上进行编译的。
很多人希望看到这一点得到支持,但到目前为止,没有人提出可能的实现,也没有人制定出详细的、明确的设计来处理上述所有棘手的极端情况。