2011-08-25 37 views
2

我剛開始自學哈斯克爾出書的「瞭解你的偉大的好哈斯克爾」,我用where rewote快速排序在第5章:哈斯克爾快速排序:分析誤差「其中」

quicksort :: (Ord a) => [a] -> [a] 
quicksort [] = [] 
quicksort (x:xs) = smaller ++ [x] ++ bigger 
    where smaller = quicksort [a | a <- xs, a <= x] 
     bigger = quicksort [a |a <- xs, a > x] 

,但是當我裝成GHCI 7.0.3,我得到了以下錯誤:

parse error on input '=' 

書上的原代碼:

quicksort :: (Ord a) => [a] -> [a] 
quicksort [] = [] 
quicksort (x:xs) = 
    let smallerSorted = quicksort [a | a <- xs, a <= x] 
     biggerSorted = quicksort [a | a <- xs, a > x] 
    in smallerSorted ++ [x] ++ biggerSorted 

你能幫我找到它爲什麼不適用於where

+0

隨着你的編輯你已經修復了縮進,所以你不應該得到解析錯誤,所以這個問題變得無法理解......? – Francesco

回答

7

這是空白的規則。您在where之後的定義必須位於相同的空格縮進處。 這將編譯:

quicksort :: (Ord a) => [a] -> [a] 
quicksort [] = [] 
quicksort (x:xs) = smaller ++ [x] ++ bigger 
    where smaller = quicksort [a | a <- xs, a <= x] 
      bigger = quicksort [a |a <- xs, a > x] 

您可能需要閱讀this

+2

作爲一條經驗法則,如果它們形成一個邏輯單位,請始終將您的行對齊到同一縮進處。 – fuz

+0

這確實是由whitespce規則造成的。 – Porco

+7

一位學者寫道......把這稱爲「空白」規則是不恰當的,因爲正確的縮進級別並不總是(並且實際上不是)由空白單獨確定。這是「佈局」規則。相關縮進級別由佈局關鍵字後的第一個標記確定。在這種情況下,關鍵字是'where',所以給定的定義必須與'smaller'的開始對齊,其縮進級別包括非空白'where'的寬度。佈局大於空白,在字母轉換下不是不變的,需要固定字體的字體! – pigworker

3

作爲附錄cldy的回答,請注意,您也可以格式化where -clauses這樣的:

quicksort :: (Ord a) => [a] -> [a] 
quicksort [] = [] 
quicksort (x:xs) = smaller ++ [x] ++ bigger where 
    smaller = quicksort [a | a <- xs, a <= x] 
    bigger = quicksort [a |a <- xs, a > x] 

我個人比較喜歡這個,因爲它可以節省一些橫向空間,而且由於大多數編輯器不能自動智能 - 使用更傳統的風格時縮進正確的列。

+0

除了我之前的評論,在行尾保留佈局關鍵字(所以塊縮進由下一行的空白量決定)在Alpha轉換下不變,並且不需要固定間距字體展現令人欽佩的橫向節儉。這是我喜歡的'where'和'of'的風格,但它似乎不太適合'let'。 – pigworker