2012-01-14 56 views

回答

11

只需使用:

fifth :: [a] -> a 
fifth l = l !! 4 

使用fifth []喜歡你的建議是錯誤的,因爲這將匹配模式列表對空列表 - 你只需要將變量名稱綁定到完整列表列表,以便以後可以使用!!函數。

你甚至可以定義功能:

fifth :: [a] -> a 
fifth = (!!4) 

這裏我們使用partial application:你通常認爲!!爲採用兩個自變量的函數:列表和一個整數。我們可以給它提供一個參數並獲得一個只需要列表的新函數(fifth)。當我們提供(!!4)一個列表,它返回的第五元素:

Prelude> let fifth = (!!4) 
Prelude> fifth [1,2,3,20,30,40] 
30 

的功能當然是部分功能,因爲它會爲小列表失敗:

Prelude> (!!4) [1,2,3,20] 
*** Exception: Prelude.(!!): index too large 

這是可以預料到。如果你願意,你可以把它安全通過讓它返回aMaybe a代替::

fifth :: [a] -> Maybe a 
fifth (a:b:c:d:e:rest) = Just e 
fifth _ = Nothing 

這裏的第一圖案將匹配長度爲5個以上的列表,第二模式匹配任何不想第一個匹配。您可以使用這樣的:

*Main> fifth [1,2,3,20,30,40] 
Just 30 
*Main> fifth [1,2,3,20] 
Nothing 

您現在已經自己被迫總是格局fifth反對任何Just aNothing結果相匹配。這意味着當您撥打電話fifth someList時,必須考慮到someList可能太短。這樣你可以確保在編譯時間那裏不會有任何運行時來自這個函數的錯誤。

+0

謝謝!有效。 – integral007 2012-01-14 08:52:29

+0

+1 @Martn'你現在強迫自己......'除非他發現如何寫不公正的,那就是...... – Ingo 2012-01-14 10:52:32

+0

@Ingo:噓,讓我們保持你和我之間的關係:-) – 2012-01-14 12:28:18

8

我將定義一個安全索引運算符!!!,然後根據!!!定義fifth

(!!!)     :: [a] -> Int -> Maybe a 
xs  !!! n | n < 0 = Nothing 
[]  !!! _   = Nothing 
(x : _) !!! 0   = Just x 
(_ : xs) !!! n   = xs !!! (n - 1) 

fifth :: [a] -> Maybe a 
fifth = (!!! 4) 
+2

這是一個很好的我的答案的概括,我喜歡! – 2012-01-14 09:54:08

5

另一個不安全變種會

fifth = head . drop 4 

但是,嘿,有時一個剛剛知道這個該死的名單將有超過4個元素。類型系統功能不足以表達它(使用標準列表,就是這樣)。

+5

安全版本:'fifth = listToMaybe。下降4' – hammar 2012-01-14 11:42:48

相關問題