2014-09-26 39 views
7

我明天正在爲測試進行培訓,以完成我對函數式編程的介紹,但有一件事我不明白。Haskell:非詳盡模式

每當我有這樣一個程序:

test [] = [] 
test (x:xs) = test (xs) 

他所做的是,他採取的第一個元素淘汰之列,並與其餘部分繼續。每當只剩下一個時,xs應該是[],而這又應該觸發test [] = []。但是每當我運行這個算法,我得到一個錯誤。 Exception: <interactive>:20:5-16: Non-exhaustive patterns in function test.

我在網上找不到明確的解釋。有人可以給我一個鏈接,這是明確解釋或解釋給我?

+1

奇怪。您發佈的代碼段不包含非窮舉模式。 – pyon 2014-09-26 07:22:18

+1

只是在黑暗中拍攝:你可能試圖將這個定義輸入到ghci中嗎?如果是這樣,你應該使用一個let語句:'let test [] = [];測試(x:xs)=測試xs'。 – pyon 2014-09-26 07:24:29

+0

是的,這就是我正在做的。非常感謝。我已經開始嚇壞了,因爲我花了整整一週的時間編程遞歸,但我無法弄清楚爲什麼這個工作不起作用。 – 2014-09-26 07:28:46

回答

24

您在問題主體中發佈的代碼確實是窮盡模式匹配。但是,如果你試圖進入這個定義成ghci中,你應該使用一個單一let聲明:

Prelude> let test [] = [] ; test (x:xs) = test xs 

你在做什麼here是不正確。您首先定義一個非詳盡的功能test

Prelude> let test [] = [] 

然後你要定義另一非詳盡的功能,也稱爲test,隱藏第一個:

Prelude> let test (x:xs) = test xs 
+1

我希望我可以更多次提升這一點。 – 2016-09-03 23:04:57

4

這是在Haskell的REPL(GHCi)中嘗試使用嬰兒程序確實是一件非常棘手的事情。

使用let不是很明顯(特別是,因爲在單獨的「腳本/程序」中不需要它)。

有時我們不想創建一個完整的文件,而是試驗一個具有不同「案例」的小函數。

另一個有用的方法是使用分隔符:{ & :}來定義我們函數的範圍。

假設我們想嘗試一個簡單的遞歸sum函數,它可以將一列數字加起來。然後我們會說:

λ > :{ 
Prelude| sum [] = 0 
Prelude| sum (x:xs) = x + sum xs 
Prelude| :} 
sum :: Num t => [t] -> t 
Prelude 
λ > sum [1..10] 
55 
it :: (Enum t, Num t) => t 

請注意我們現在看到我們的功能的程度如何很好!

希望這會有所幫助。乾杯!