为什么Hackage将模块链接到其他源文件?

时间:2018-10-25 13:16:16

标签: haskell hackage

我试图了解Hackage显示的基本软件包的结构。在https://bla之后,模块名称必须反映其来源的路径;引用以上内容:

  

文件名是模块的名称加上.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接口文件。

因此,我的问题是: 如何解释差异?黑客展览上到底显示了什么?

预先感谢您对此事的任何见解!

1 个答案:

答案 0 :(得分:1)

从模块导入的名称可以重新导出。发生这种情况时,hadock会帮助您将名称链接到名称的原始来源,而不是重新导出模块中的导入行。它遵循您的间接性。这就是您的情况。因此,以(++)(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 (++) -} )

所以您可以看到haddock实际上跟随了两个链接:(++)是从Data.OldList导入的,甚至在那里也被重新导出了。

编译器也仔细跟踪定义了名称的原始模块;如果您导入所有Data.ListData.OldListGHC.Base,您会发现仍然可以使用(++),即使乍一看似乎很含糊您是指(Data.List.++)(Data.OldList.++)还是(GHC.Base.++)中的哪个。由于所有三个实际最终都解析为(GHC.Base.++),因此没有歧义。