2010-03-19 64 views
1

我有這個,但我得到了一個錯誤:如何檢測Haskell中的列表是否包含3個項目?

-- test if a list contains exactly three characters 
test :: [Char] -> Bool 
test xs | [_ , _ , _] = True 
      | otherwise = False 
+0

我不得不說,我更喜歡'[_,_,_]'到'[_,_,_]'。 – MatrixFrog 2010-03-19 21:10:42

+0

你有什麼錯誤? – 2010-03-19 21:18:36

+0

這裏的答案比我要求的要多。謝謝。 – unj2 2010-03-19 22:15:28

回答

12

模式匹配發生在左側豎線的側。因此:

test :: [Char] -> Bool 
test [_, _, _] = True 
test _   = False 

Norman Ramsey下面正確地指出,下面的代碼是健壯替代的解決方案(因爲它是當施加到(長)的有限列表非常低效和無限列表不停止),並應因此使用:

test :: [Char] -> Bool 
test xs = length xs == 3 

此外,length xs == 0應始終null xs代替。

編輯:自然產生的問題是:我們如何概括這個?如果我們想測試一個列表是否完全是n元素,該怎麼辦?如果輸入可能是無限的呢? 這裏有一個解決方案,其中的成本或者是n或列表,取其較小者—的長度,這就是高效的解決方案,漸進,因爲我們都不可能希望:

hasLength :: Int -> [a] -> Bool 
hasLength n []  = n == 0 
hasLength 0 (x:xs) = False 
hasLength n (x:xs) = hasLength (n-1) xs 

用法:

*Main> hasLength 3 [1..2] 
False 
*Main> hasLength 3 [1..3] 
True 
*Main> hasLength 3 [1..4] 
False 
*Main> hasLength 3 [1..] 
False 

這是不安全調用此函數負長度;如果列表是無限的,函數將不會終止,並且如果列表是有限的,它將返回False,其成本與列表的長度成比例。一個簡單的解決辦法是事先檢查(僅在第一次通話時)n是非負的,但是這種修復會使代碼變得難看。

+0

呃!我和你在一起,直到「長度」的例子。這太類似於經典的初學者錯誤:寫'length xs == 0'而不是'null xs'。 – 2010-03-19 21:16:18

+0

或者如果你想要看起來,我認爲這個無點形式應該是'test =(3 ==)。長度' – MatrixFrog 2010-03-19 21:20:47

+0

@Norman:嗯,'null'怎麼會在這裏幫忙? – Stephan202 2010-03-19 21:28:18

相關問題