为什么Haskell导入的这些极端案例 - 作为工作,他们做了什么?

Bak*_*riu 8 import haskell

我遇到过一些包含特别奇怪的导入的模块.

首先,我看到一个模块A将自己的其他模块导入.例如:

-- module A.hs
module A where
import B as A   -- ???

f = id
Run Code Online (Sandbox Code Playgroud)

这是做什么的?为什么上面允许这样做?

然而,最困扰我的是代码实际上是这样的:

module A where
import B as A  -- Okay, assume this works...
import C as A  -- ??? A is already defined!

f = id
Run Code Online (Sandbox Code Playgroud)

为什么可以使用相同名称导入多个模块?这实现了什么?我认为import不允许使用这些类型,而且Haskell的温和介绍说:

将具有相同名称的两个不同实体导入同一范围是非法的.

但是这些进口工作正常.然而另一件令我烦恼的奇怪事情就是导出模块本身:

module A (module A) where
Run Code Online (Sandbox Code Playgroud)

总结一下,鉴于以下MWE:

-- A.hs
module A (module A) where
import B as A
import C as A

f = id

-- B.hs
module B where

g = id

-- C.hs
module C where

h = id
Run Code Online (Sandbox Code Playgroud)
  1. 进口是遵循标准还是GHC的一些错误?它看起来不像一个bug,但我找不到任何解释所有这些角落情况的参考.
  2. 取得了什么确切的结果?我的意思是:从哪些名称导入和/或导出A

lef*_*out 6

名称限定符与模块名称不同.名称限定符只是一个集合范围,您可以使它引用任意数量的模块.通常情况下,您不会添加多个,但在一种情况下,您几乎总是添加大量模块:在不合格的范围内.import Data.List可能会被解读为import qualified Data.List as "":它安排说,sortBy当用"空限定符"引用它时,即没有.但我们可以"重命名"该范围:

module Main where

import qualified Prelude as P
import qualified Data.List as P
import qualified Data.Ord as P

main :: P.IO ()
main = do    -- `do` is syntax, not a name!
   P.print  P..  P.map  P.snd  P.$  P.sortBy  (P.comparing  P.fst)
     [(4,'o'),(6,' '),(0,'H'),(1,'e'),(3,'l'),(9,'r'),(7,'W'),(10,'l'),(8,'o'),(2,'l'),(5,','),(11,'d'),(12,'!')]
Run Code Online (Sandbox Code Playgroud)

唯一被修复的限定符是文件本身中模块特有的限定符:它们始终都在不合格的范围内,并且在范围内自动以模块命名.对于定义,您必须使用不合格的表单.

因为module A (module A),这看起来非常虚伪.我不认为模块出口是真正经过深思熟虑的.它们仅在您引用实际模块时才能正常工作,而不仅仅是名称限定符,即

module PowerPrelude (module A)
import qualified Prelude as A
import qualified Data.List as A
import qualified Data.Ord as A
Run Code Online (Sandbox Code Playgroud)

无法正常工作.这让你想知道为什么允许宣布这样的出口.这可能确实是一个错误.