如何修改下面的函數,使得列表比搜索索引短的情況會導致錯誤。Haskell列表索引超出範圍
elementAt::Int -> [Int] -> Int
elementAt = Data.Foldable.foldl (\x y -> if x == 0 then y else x-1)
1是第一元件
如何修改下面的函數,使得列表比搜索索引短的情況會導致錯誤。Haskell列表索引超出範圍
elementAt::Int -> [Int] -> Int
elementAt = Data.Foldable.foldl (\x y -> if x == 0 then y else x-1)
1是第一元件
的使用摺疊來查找列表中的第n個元素是一個相當困難的方式的索引。我想向您介紹使用顯式遞歸一個簡單的方法:你必須看看這個問題,不同的
:
方法的類型簽名給出:
只擔心第一點elementAt :: Int -> [Int] -> Int
,我們知道,如果索引0
,我們要返回元素:
elementAt 1 (x:_) = x
現在如果我們的號碼大於1
呢?在這種情況下,我們希望減少我們的索引結束測試下一項的謂詞:
elementAt n (x:xs) = elementAt (n-1) xs
現在我們差不多完成了!如果我們想,如果在指定位置的元素沒有找到引發錯誤,我們可以簡單地使用error
:
elementAt _ _ = error "Element not found!"
但這不是慣用的Haskell方式是如何工作的。一個可能的解決方案是使用一個Maybe
包裹的結果對於這一點,我們必須改變類型簽名一點點:
elementAt :: Int -> [Int] -> Maybe Int
現在的功能是能夠以如果指定的位置返回Just
元素存在和Nothing
否則:
elementAt 1 (x:_) = Just x
elementAt n (x:xs) = elementAt (n-1) xs
elementAt _ _ = Nothing
爲了完整起見,在這裏一個可能的方式實現這一目標,雖然摺疊:
elementAt n = foldl (\acc x -> if fst x == n then snd x else acc) n . zip [1..n]
即使您嘗試獲取列表範圍內的元素,我認爲這個函數是錯誤的。例如,'elementAt 0 [1,2,3]'將返回'3'。 – WilQu 2015-02-10 10:11:04
我認爲顯式遞歸在這種情況下比褶皺更容易使用。 – chi 2015-02-10 10:20:41
1被認爲是我忘記提及的索引元素,因此0被認爲是越界 – yonutix 2015-02-10 11:17:12