GHC拒绝出口合格的模块

Joh*_*kin 18 haskell module

我想写一个模块,它重新导出一些已导入的模块.像这样的东西:

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
Run Code Online (Sandbox Code Playgroud)

这看起来应该有效; 但是,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
Run Code Online (Sandbox Code Playgroud)

GHCI拒绝加载他们的出口.

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

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

Yit*_*itz 13

不,这不仅仅是GHC的限制,它是导入和导出设计在Haskell中工作的方式.

模块只能控制自己的命名空间 - 它不会影响人们从其他命名空间中看到的内容.一个模块"重新导出"只是一个简写,说"导出我自己的命名空间中的所有符号,这些符号恰好是从其他模块导入的".但是您导入限定的符号实际上并不在您自己的命名空间中.

如果要导出两个具有相同名称的不同符号,则无法从一个模块执行此操作.将模块拆分为两个,然后从另一个模块导出每个版本.

  • 但是可以重新输出合格的符号; 例如,`import qualified Foo.B`将让我做`module Foo.A(Foo.B.sym)`.为什么这不可能与模块一起使用?我没有导出两个同名的符号; 任何冲突的东西都是模块内部的. (4认同)

小智 6

当导入模块根据合格导入的声明重新声明导入模块中的某些名称时,此限制也很方便.例如:

module MyPrelude (succ, module Prelude) where

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

succ :: ...
succ = ... P.succ ...
Run Code Online (Sandbox Code Playgroud)

如果没有很多冗长的话,这个成语真的很难表达.另外,问问你自己"没有分层模块会有意义吗?".如果没有,那么这是非常具体的,并且当从表达式引用分层模块名称时实际上发生的事情根本不是分层的.

至于为什么你能够重新导出由你没有导入的某个模块名称限定的单个符号,这似乎是让hehrchical模块在ghc中以heirachically工作的kludge.在导入Foo时获得Foo.B限定符号.A是神奇的,我认为它是因为Foo这个名字不再是Foo.A的实际的heirachical祖先,但出于具有替代资格的东西的预期用途是在使用它的情况下来自Foo.如果没有GHC扩展,我认为这种行为根本没有意义,因此我将大胆猜测其GHC的具体情况.