2012-01-25 33 views
2

在Haskell ghci中,我試圖裝載名爲.hs腳本入解釋

Prelude> :load filename.hs 
Ok, modules loaded: Main. 

不幸的是我不能運行任何的文件中定義的功能。我沒有任何錯誤地編譯文件,但調用函數給出了一個錯誤,「不在範圍內:(函數名)」。奇怪的是,一段時間以前,我沒有問題,運行這...

+0

你能顯示文件的前幾行嗎?具體來說就是'module'聲明,如果有的話。 – ehird

+0

該文件編譯正常,並且沒有模塊聲明。當我點擊編輯器中的「編譯」按鈕時,似乎失敗了,然後在ghci中加載。 – NoBugs

+1

如果你沒有模塊聲明,它默認爲'module Main(main)where',編譯時只能訪問'main'函數。 –

回答

3

的問題是,你的編輯器編寫的東西代碼類似

$ ghc foo.hs 

因爲你的文件沒有一個模塊聲明,GHC假定模塊稱爲Main,因爲你沒有另行指定並且由於它正在編譯完整程序,所以不會輸出main之外的任何其他定義;也就是說,它充當如果你有一個模塊聲明,如:

module Main (main) where 

而GHCI默認爲:

module Main where 

這些module declarations指定所編譯模塊的名稱,和值出口。在第一個聲明中,只有main從模塊中導出;在第二種情況下,每個頂級值都會導出。未導出的值無法從模塊外部訪問,這就是爲什麼您在GHCi中出現「不在範圍內」的錯誤原因。

GHCi的不一致的行爲大概是爲了使測試代碼更容易;您不必擁有模塊聲明來加載文件並使用其定義。解決方案是將module Main where(或其他模塊名稱)放在文件的頂部,它明確地導出所有內容。就我個人而言,我認爲這種行爲很混亂,GHC和GHCi的行爲可能應該改變爲一致。

0

很難準確地猜出問題是什麼。你從像改變文件的頂部行:

module Main where 

喜歡的東西:

module Main (main) where 

如果你沒有,那就只導出main功能。

+0

不,我沒有使用模塊。 「模塊」是做什麼的? – NoBugs

+0

@NoBugs模塊聲明允許您在編譯時控制可用於導入其他模塊或ghci提示符的內容。我強烈建議在每個源文件中都有一個模塊聲明,明確出口有助於避免不愉快的意外。 –

1

語言標準規定,如果沒有給出模塊聲明,則隱含地爲module Main (main) where。當Haskell源文件被編譯並加載到ghci中時,只有相關模塊的導出實體處於範圍之內。在你的情況下,沒有模塊聲明,那只是main函數。

但是,由於開發時相當不方便,ghci可以加載解釋的模塊具有更廣泛的範圍,參見。 the users' guide。以該形式加載的模塊在提示中的模塊名稱之前用星號表示,對於這樣的模塊,不僅模塊中定義的每個頂層實體都在範圍內,而且還包括導入的實體,當模塊以該形式加載時,模塊的級別也可以在ghci提示符下使用。

這允許在開發中方便地測試函數,因此是一件好事™。另一方面,正如赫爾提到的那樣,行爲上的差異可能會引起混淆,因此是一件壞事。總體而言,我認爲ghci的更廣泛的優勢在於*Module s超過了不一致性。

0

您可能以前編譯過該模塊,因此有.o.hi文件處於目錄中。當GHCi發現這些時,默認情況下它會以編譯模式加載模塊,這意味着只有從模塊導出的東西在範圍內。

如果您沒有包含模塊聲明,默認情況下這將默認爲main,因爲默認模塊聲明爲module Main (main) where。這也是Main名稱的來源。

您可以從提示中知道發生了這種情況。通常情況下,加載的模塊,它看起來就像這樣:

Prelude> :load Foo.hs 
[1 of 1] Compiling Main    (Foo.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> 

Main之前的星號意味着,該模塊是在解釋模式下打開,並在這一切都在範圍內,包括來自其他模塊的進口的東西。但是,如果我剛剛編譯Foo.hs,然後試圖將其加載到GHCI,我反而看到這樣的事情:

Prelude> :load *Foo.hs 
[1 of 1] Compiling Main    (Foo.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> 

Prelude> :load Foo.hs 
Ok, modules loaded: Main. 
Prelude Main> 

您可以用星號前綴的文件名強制解釋模式

0

不知道這是否有幫助,但我只是有同樣的問題。

發現我運行GHCI的虛擬空間不足,所以當我保存我的文件時,它們是空的。

試圖加載文件看起來像它成功(Whatever.hs,解釋) - 但我得到了同樣的錯誤。