为什么在源文件的开头指定模块名称是必须的?

时间:2014-08-23 14:59:14

标签: file haskell module

GHC坚持认为模块名称必须等于文件名。但如果它们是相同的,那么为什么Haskell编译器需要两者?对我来说似乎多余。这只是一个语言设计错误吗?

除了不方便之外,它还引发了一个问题,即如果我想使用2个意外具有相同顶级模块名称的库,那么我就不能简单地通过重命名其中一个文件夹来消除歧义。这个问题的惯用解决方案是什么?

3 个答案:

答案 0 :(得分:8)

Haskell语言规范没有谈论文件。它只讨论模块及其语法。所以显然没有语言设计错误。

GHC编译器(以及许多其他人)选择遵循每个文件一个模块的模式,并在具有匹配名称的文件中搜索模块。对我来说似乎是一个体面的策略。否则,您需要为编译器提供从模块名称到文件名的一些映射,或者使用的每个文件的显式列表。

答案 1 :(得分:2)

我想说,其中一个重要原因是你总是希望模块名称是附加文件名的文件的路径。这与Java,C#和其他许多在源代码中更喜欢显式名称空间声明的语言相同,在许多情况下,显式优于隐式。它使程序员可以最大限度地控制文件名,而不必将其与文件名绑定。

想象一下,我是日本的Haskell程序员,我的操作系统使用日文字符作为文件名。我可以尽可能使用日文字符编写源代码,但我也想导出使用ASCII字符的API。如果模块名称和文件名必须相同,这将是不可能的,并且会使其他国家的人们很难使用我的库。

正如@chi指出的那样,如果你有两个包含冲突模块名称的软件包(根据我的经验非常罕见),你总是可以使用软件包限定的导入。

答案 2 :(得分:-3)

Haskell语言规范要求模块由模块头启动,并且不提及文件 - 它为实现编译器提供了关于文件的完全自由。因此,Haskell语言缺乏表达包含模块的文件的位置的能力。因此,一些编译器[包括最重要的编译器:GHC]使用一个简单的解决方案:模块的名称必须匹配从include目录到文件的路径。这引入了冗余。

为避免冗余,编译器可能会删除语言规范中的要求,以通过标头启动每个模块。然而,他们选择不这样做只是为了确认规范。也许GHC语言扩展可以做到这一点,但目前没有这样的扩展。

因此问题是语言设计错误,并继续存在。

为了解决独立图书馆之间可能的名称冲突,GHC扩展Package-qualified imports似乎是最好的方式。