GHC拒绝出口合格模块

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

我想写一个模块,它把它导入的一些模块重新导出。就像这样:

module Foo.A
  ( module Foo.B
  , module Foo.C
  ) where
import qualified Foo.B
import qualified Foo.C

-- bunch of code using Foo.B and Foo.C here

这看起来应该有效;但是,GHC会打印关于出口的警告:

Foo/A.hs:2:5:
    Warning: the export item `module Foo.B' exports nothing

Foo/A.hs:3:5:
    Warning: the export item `module Foo.C' exports nothing

GHCI拒绝从他们那里出口货物。

我可以通过不限定导入来解决这个问题,但是在这些导入和主模块代码之间可能会出现命名冲突。

有没有办法让GHC输出这些模块?

提问于
用户回答回答于

不,这不仅仅是GHC的一个限制,它是在Haskell设计的进出口方式。

模块只控制自己的命名空间--它不会影响人们从其他名称空间中看到什么。一个模块“再导出”只是一个缩写,用来表示“导出我自己命名空间中碰巧从另一个模块导入的所有符号”。但是,导入的限定符号实际上并不在您自己的命名空间中。

如果想要导出两个具有相同名称的不同符号,将无法从一个模块中导出。将模块分成两部分,并从不同的模块导出每个版本。

用户回答回答于

当导入模块打算根据限定导入的声明重新声明导入模块中的某些名称时,这种限制也是一种方便。例如:

module MyPrelude (succ, module Prelude) where

import qualified Prelude as P (succ)
import Prelude hiding (succ)

succ :: ...
succ = ... P.succ ...

这个成语如果没有很多冗长的话就很难表达。另外,问问你自己:“如果没有分层模块,这有意义吗?”。如果不是,那么这是非常特定的GHC,当从表达式引用分层模块名称时实际上正在进行的是不分层的。

至于为什么能够再导出由某些模块名限定的单个符号,这似乎是一种让继承模块在GHC中继承工作的传说。当导入foo.A时获取foo.b限定符号是神奇的,我认为这是因为foo这个名称与foo.A相比,并不是一个实际的传家宝祖先,但是导出具有替代条件的东西的目的是在从foo中使用的情况下。如果没有GHC扩展,我认为这种行为根本就没有意义,所以我要大胆地猜测它的GHC的特殊性。

扫码关注云+社区