2014-05-02 49 views
8

我遇到過一些包含特別奇怪的輸入的模塊。爲什麼在Haskell的導入中這些角落案例如何工作?他們做了什麼?

首先,我看到一個模塊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 
  1. 是進口採用的標準或這是一些bug然而,這錯誤我是出口模塊本身的其他奇怪的事情GHC?它看起來不像一個bug,但是我找不到任何可以解釋所有這些角落案例的參考。
  2. 取得的確切結果是什麼?我的意思是:哪些名稱是從A導入和/或導出的?
+1

我從來沒有見過從本身導出模塊;那很有意思。所有其他情況下,不同導入中的名稱都是聯合的。例如。第一個例子:A.somethingInB引用B的版本,但是A.f引用A的版本(除非B也定義了f,那麼這是一個模糊性錯誤)。幸運的是,這可以簡單地概括爲:-) – luqui

回答

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),這似乎非常虛假。我不認爲模塊出口是真的很好的思路。當你指的是實際的模塊,而不僅僅是一個名限定符他們只是正常工作,即

module PowerPrelude (module A) 
import qualified Prelude as A 
import qualified Data.List as A 
import qualified Data.Ord as A 

工作。這讓你想知道爲什麼它可以聲明這樣的出口。這可能確實是一個bug。

+0

如果您希望重新導出一些模塊和整個當前模塊:'module A(module A; module B; module C),那麼顯式導出整個當前模塊會非常有用;進口B;導入C; ......如果這是不可能的,你將不得不在出口中的'A'中指定每一個聲明。 – user2407038

+0

沒錯。雖然這並不能解釋爲什麼導出一個實際上不是模塊名稱的「模塊」範圍並不是錯誤 - 「PowerPrelude」示例編譯的內容,只是它不會暴露任何東西! – leftaroundabout

+0

在你的最後一個例子中,你添加了一個「合格」,這在我的情況下不存在。事實上,這些名稱*都是在我的代碼中導出的......我沒有得到的是用例。對我來說,看起來像'模塊A(模塊A),其中導入B作爲A'完全等同於'模塊A(模塊B)導入B',或者不是嗎? – Bakuriu

相關問題