解析边缘案例Haskell模块导入和导出
我正在编写一个小Haskell编译器,我想实现尽可能多的Haskell 2010。我的编译器可以解析一个模块,但将模块完成到一个程序似乎是一项不平凡的任务。我编写了一些棘手但可能有效的Haskell模块示例:解析边缘案例Haskell模块导入和导出,haskell,compiler-construction,compilation,Haskell,Compiler Construction,Compilation,我正在编写一个小Haskell编译器,我想实现尽可能多的Haskell 2010。我的编译器可以解析一个模块,但将模块完成到一个程序似乎是一项不平凡的任务。我编写了一些棘手但可能有效的Haskell模块示例: module F(G.x) where import F as G x = 2 这里模块F导出G.x,但是G.x与F.x相同,因此模块F导出x如果且仅当它导出x module A(a) where import B(a) a = 2 module B(a) where
module F(G.x) where
import F as G
x = 2
这里模块F
导出G.x
,但是G.x
与F.x
相同,因此模块F
导出x
如果且仅当它导出x
module A(a) where
import B(a)
a = 2
module B(a) where
import A(a)
在本例中,为了解析模块A
的导出,编译器必须检查从B
导入的A
是否与声明的A=2
相同,但是B
导出A
如果且仅当A
导出A
module A(f) where
import B(f)
module B(f) where
import A(f)
在解析模块A
期间,编译器可能假设从B
导入的f
存在,这意味着A
导出f
,因此B
可以导入A(f)
并导出f
。唯一的问题是在任何地方都没有定义f
:)
在这里,模块
导出导致导出列表相互依赖,也相互依赖
根据Haskell 2010规范的定义,所有这些示例都应该是有效的Haskell
我想问一下,是否知道如何正确、完整地实现Haskell模块
假设模块只包含(简单的)变量绑定,导入
s(可能带有as
或限定
),并导出可能限定的变量列表和模块…
缩写。算法必须能够:
- 计算每个模块导出变量的有限列表
- 将每个导出变量链接到其绑定
- 将每个模块中使用的每个(可能是限定的)变量链接到其绑定
回答您的问题:递归模块是通过计算一个固定点来处理的 从模块图中的强连接组件开始。对于此组件中的每个模块,您首先假设它不导出任何内容。然后重新访问这些模块,并根据新信息计算新的导出列表。您可以证明这个过程是单调的——每次导出列表增长(或者至少不会收缩)。它迟早会停止生长——那么你已经到达了固定点
您可以通过借用静态分析的一些想法来优化此算法(该社区非常擅长计算固定点),但我的软件包目前实现了naive算法()。Wow,谢谢,我甚至不希望有针对此问题的论文和库:)
module A(module X) where
import A as X
import B as X
import C as X
a = 2
module B(module C, C.b) where
import C
b = 3
module C(module C)
import B as C
c = 4