我有這個,但我得到了一個錯誤:如何檢測Haskell中的列表是否包含3個項目?
-- test if a list contains exactly three characters
test :: [Char] -> Bool
test xs | [_ , _ , _] = True
| otherwise = False
我有這個,但我得到了一個錯誤:如何檢測Haskell中的列表是否包含3個項目?
-- test if a list contains exactly three characters
test :: [Char] -> Bool
test xs | [_ , _ , _] = True
| otherwise = False
模式匹配發生在左側豎線的側。因此:
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
是非負的,但是這種修復會使代碼變得難看。
呃!我和你在一起,直到「長度」的例子。這太類似於經典的初學者錯誤:寫'length xs == 0'而不是'null xs'。 – 2010-03-19 21:16:18
或者如果你想要看起來,我認爲這個無點形式應該是'test =(3 ==)。長度' – MatrixFrog 2010-03-19 21:20:47
@Norman:嗯,'null'怎麼會在這裏幫忙? – Stephan202 2010-03-19 21:28:18
我不得不說,我更喜歡'[_,_,_]'到'[_,_,_]'。 – MatrixFrog 2010-03-19 21:10:42
你有什麼錯誤? – 2010-03-19 21:18:36
這裏的答案比我要求的要多。謝謝。 – unj2 2010-03-19 22:15:28