0

我试图了解 Hackage 显示的基本包的结构。在https://en.wikibooks.org/wiki/Haskell/Modules之后,模块名称必须反映其源的路径;引用上述内容:

文件名是模块名加上 .hs 文件扩展名。任何点“。” 在模块名称中更改为目录。

以 Data.List 为例,这让我相信在路径 ../Data/List.hs 下应该有一个源文件,然后包含

module Data.List where ...

(模导出列表)。

另一方面,如果我浏览 Hackage 上的 Data.List 模块并点击“# Source”链接,我会被定向到各种不同模块的源文件。其中有:GHC.Base、Data.OldList、Data.Foldable、GHC.List。

首先,我本地安装的基础包显然包含一个 ../Data/List.hi 接口文件。

因此,我的问题是:如何解释这种差异?Hackage 上真正展示了什么?

提前感谢您对此事的任何见解!

4

1 回答 1

1

从模块导入的名称可以重新导出。发生这种情况时,黑线鳕有助于将您链接到名称的原始来源,而不是重新导出模块中的导入行;它遵循你的间接性。这就是你的情况。因此以(++)(Data.List 的黑线鳕中的第一个函数)为例,代码结构如下:

 -- GHC/Base.hs
 module GHC.Base where
 (++) = ...

 -- Data/OldList.hs
 module Data.OldList ( (++) {- re-exports GHC.Base's (++) -}, ... ) where
 import GHC.Base -- brings (++) into scope

 -- Data/List.hs
 module Data.List ( (++), ... ) where
 import Data.OldList hiding ( ... {- does not mention (++) -} )

所以你可以看到黑线鳕实际上遵循了两个链接:(++)从 进口Data.OldList,甚至在那里它是再出口。

编译器也会仔细跟踪定义名称的原始模块;如果你导入所有的Data.List, Data.OldList, 和GHC.Base,你会发现你仍然可以使用(++),即使乍一看似乎它可能是模棱两可的(Data.List.++), (Data.OldList.++), 或者(GHC.Base.++)你的意思。由于所有三个实际最终都解析为(GHC.Base.++),因此没有歧义。

于 2018-10-25T13:36:20.100 回答