Используя складку, чтобы найти п-й элемент в списке является довольно сложным способом. Я хочу представить вам простой способ с использованием явной рекурсии:
Вы должны взглянуть на эту проблему по-разному:
- Что такое мой базовый случай?
- Как должен выглядеть рекурсивный вызов?
- (необязательно) Как насчет ошибок?
сигнатура типа метода будет дан:
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
Я считаю, что явная рекурсия проще использовать в этом случае, чем складки. – chi
1 считается элементом индекса, который я забыл упомянуть, таким образом, 0 считается за пределами – yonutix