2017-02-12 52 views
0

Begginer Haskell問題。 其實我發現非常相似的問題Haskell error: "non-exhaustive patterns"另一個'功能非窮舉模式'

交互的shell:

Prelude> merge [] [] = [] 
Prelude> merge (x:xs) [] = x:xs 
Prelude> merge [] (y:ys) = y:ys 
Prelude> -- merge (x:xs) (y:ys) 

Prelude> merge [][] 
Exception 
Prelude> merge [0][] 
Exception: <interactive>:3:1-22: Non-exhaustive patterns in function merge 

Prelude> merger [][0] 
OK 

事實上例外也存在於非交互式模式

main = do 
    print (merge [1,2,3] []) 
    print (merge [] [1,2,3]) 
    print (merge [] []) 


merge :: (Ord a) => [a] -> [a] -> [a] 
merge (x:xs) [] = x:xs 
merge [] (y:ys) = y:ys 
merge [][] = [] 

但是這取決於particulas合併的特殊情況下的順序出現錯誤。 我不知道爲什麼會發生這種情況。提前致謝。

回答

6

這裏有兩個單獨的問題。

您不可能在GHCi中以這種方式定義 merge(感謝修正,亞歷克!)

的第一個問題,這只是發生在互動環節中,是你定義單獨的函數調用merge,每個陰影前一個。對於與您的問題非常相似的人,請參閱here

要進入一個多定義,必須使用:{:}

Prelude> :{ 
Prelude| merge [] [] = [] 
Prelude| merge (x:xs) [] = x:xs 
Prelude| merge [] (y:ys) = y:ys 
Prelude| -- merge (x:xs) (y:ys) 
Prelude| :} 
Prelude> 

然而,在一般情況下,進入多定義爲GHCI是相當不愉快,所以你最好存儲你定義成一個正常的.hs文件,然後將該文件加載到GHCi中。


的第二個問題,即:在交互式會話和非交互式程序發生,那是你的merge定義並不詳盡:的情況下當兩個列表參數都是非空不被處理。請注意:

  • 如果任一列表參數爲空,merge必須返回另一個列表。
  • 如果兩個列表都不爲空,merge必須提取最小的頭元素(在任一列表中),然後遞歸合併剩下的元素。

因此,merge正確的定義是:

Prelude> :{ 
Prelude| merge xs [] = xs 
Prelude| merge [] ys = ys 
Prelude| merge [email protected](x:xs) [email protected](y:ys) 
Prelude| | x <= y = x : merge xs yys 
Prelude| | otherwise = y : merge xxs ys 
Prelude| :} 
Prelude> merge [1,3..9] [2,4..10] 
[1,2,3,4,5,6,7,8,9,10] 
Prelude> 

或者非交互:

merge xs [] = xs 
merge [] ys = ys 
merge [email protected](x:xs) [email protected](y:ys) 
    | x <= y = x : merge xs yys 
    | otherwise = y : merge xxs ys 
+0

不幸的是,GHC的最新版本並讓用戶忽略'let',所以每一行都會覆蓋前面的一行 – Alec

+0

@Alec:TIL。謝謝! – pyon

+0

請注意,您不僅糾正了語法錯誤,還更正了代碼。由於沒有'merge(x:xs)(y:ys)= ..'case – user2407038