2011-05-28 23 views
10

剛開始學習Haskell。在Haskell中調用函數 - 初學者問題

我有這裏面空的源文件:

pe :: (Integral a) => a -> a 
pe y = sum [x | x <- [1..y-1], x `mod` 3 == 0 || x `mod` 5 == 0] 

現在,如果我GHCI這一點,我可以叫PE,像這樣:

*Main> pe 1000 
233168 

我如何把它從我的源代碼中文件?如果我有

pe 1000 

它返回一個神祕的錯誤:

GHC stage restriction: `pe' 
    is used in a top-level splice or annotation, 
    and must be imported, not defined locally 
In the expression: pe 1000 

我需要聲明它主要還是什麼?

回答

11

是的,你需要把它連接到你的main函數。例如,

main = print (pe 1000) 

如果您希望擁有多個電話,你可以用do -notation將它們結合起來:

main = do 
    print (pe 500) 
    print (pe 1000) 
+4

或'main = mapM_(print.pe)[1..1000]'如果您需要爲大量的值進行操作。 – alternative 2011-05-28 00:20:18

10

一個Haskell源文件中包含的定義,而不是表達的序列。所以你不能只在文件的頂層放置一個表達式,你必須把它放在定義體內。因此,由於pe 1000不是一個定義,所以會出現錯誤。

但爲什麼這樣一個神祕的錯誤信息呢? GHC有一個名爲Template Haskell的擴展,它允許您在編譯時以編程方式創建定義。爲了達到這個目的,它允許你在一個通常只允許定義的地方放置一個表達式,並在編譯時計算表達式,並用它的結果替換表達式(它必須是一個定義) - 這稱爲拼接,然後表達式就是稱爲拼接。這樣的剪接需要滿足兩個要求:

  1. 在表達式中使用的任何標識符必須在不同的源文件中定義(這是必需的,以便在遇到表達式時所使用的功能已經編譯的,因此可以是在編譯期間調用)
  2. 表達式的類型必須是表示有效定義的模板Haskell類型。

因此,由於您的表達式pe 1000出現在只允許定義的地方,因此GHC認爲它是拼接。然而,由於它不符合上述第一條標準,即它在當前文件中被定義而不是不同的文件,GHC抱怨這一點。當然,它也不符合第二個條件,但是當它產生錯誤信息時,GHC還沒有做到這一點。如果pe在不同的源文件中定義,您會收到一條錯誤消息,抱怨pe的類型錯誤。

+0

謝謝;非常感激。 – 2011-05-28 23:07:15