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

首先,我看到了一个模块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
  • 进口是否遵循标准,或者这是GHC的错误?它看起来不像是一个错误,但是我找不到任何解释所有这些极端情况的引用。
  • 取得的确切结果是什么?我的意思是:哪些名称是从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,'!')]
    

    固定的唯一限定符是文件本身中模块特定的限定符:总是在非限定范围内,并且在模块自动命名的范围内。对于定义,您必须使用非限定形式。

    对于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
    

    不管用。这使您想知道为什么允许它完全声明这样的导出。在这里确实可能是一个错误。

    关于haskell - 为什么在Haskell的import-as工作中出现这些极端情况,它们又是怎么做的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23424293/

    10-11 22:35
    查看更多