我遇到过一些包含特别奇怪的导入的模块.
首先,我看到一个模块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)
A
?名称限定符与模块名称不同.名称限定符只是一个集合范围,您可以使它引用任意数量的模块.通常情况下,您不会添加多个,但在一种情况下,您几乎总是添加大量模块:在不合格的范围内.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)
将无法正常工作.这让你想知道为什么允许宣布这样的出口.这可能确实是一个错误.