我遇到过一些包含特别奇怪的导入的模块。
首先,我看到一个模块A
将其他模块作为自己导入。例如:
-- module A.hs
module A where
import B as A -- ???
f = id
这是做什么的?为什么上面允许这样做?
然而,最困扰我的是代码实际上是这样的:
module A where
import B as A -- Okay, assume this works...
import C as A -- ??? A is already defined!
f = id
为什么可以使用相同名称导入多个模块?这实现了什么?
我认为这些import
不被允许,A Gentle Introduction to Haskell也表示:
导入两个具有相同名称的不同实体是非法的 进入相同的范围。
然而,这些进口工作正常。还有一件让我烦恼的奇怪事情就是导出模块本身:
module A (module A) where
总结一下,鉴于以下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
A
?答案 0 :(得分: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,'!')]
,即没有。但我们可以重命名"范围:
module A (module A)
修复的唯一限定符是文件本身中模块特有的限定符:它们始终都在不合格的范围内,并且在范围内自动以模块命名。对于 definitions ,您必须使用不合格的表单。
对于module PowerPrelude (module A)
import qualified Prelude as A
import qualified Data.List as A
import qualified Data.Ord as A
,这看起来非常虚伪。我不认为模块出口是经过深思熟虑的。它们仅在您引用实际模块时才能正常工作,而不仅仅是名称限定符,即
{{1}}
将不工作。这让你想知道为什么它允许宣布这样的出口。这可能确实是一个错误。