У меня есть список, и теперь я хочу n-й элемент. В Haskell я использовал бы !!
, но я не могу найти вариант вяза.
Как получить элемент списка по индексу в вязах?
Ответ 1
В Вязе нет эквивалента. Конечно, вы могли бы реализовать это самостоятельно.
(Примечание. Это не "общая" функция, поэтому создает исключение, когда индекс выходит за пределы диапазона).
infixl 9 !!
(!!) : [a] -> Int -> a
xs !! n = head (drop n xs)
Лучше всего было бы определить общую функцию, используя тип данных Maybe.
infixl 9 !!
(!!) : [a] -> Int -> Maybe a
xs !! n =
if | n < 0 -> Nothing
| otherwise -> case (xs,n) of
([],_) -> Nothing
(x::xs,0) -> Just x
(_::xs,n) -> xs !! (n-1)
Ответ 2
Elm добавил массивы в 0.12.1.
import Array
myArray = Array.fromList [1..5]
myItem = Array.get 2 myArray
Массивы индексируются нулями. В настоящее время отрицательные индексы не поддерживаются (облом, я знаю).
Обратите внимание, что myItem : Maybe Int
. Elm делает все возможное, чтобы избежать ошибок времени выполнения, поэтому доступ за пределами границ возвращает явный Nothing
.
Если вы обнаружите, что хотите индексировать в список, а не брать голову и хвост, вам следует рассмотреть возможность использования массива.
Документация массива Важно: Реализация основного массива нарушена; используйте этот!
Ответ 3
Я использовал это:
(!!): Int -> List a -> Maybe a
(!!) index list = -- 3 [ 1, 2, 3, 4, 5, 6 ]
if (List.length list) >= index then
List.take index list -- [ 1, 2, 3 ]
|> List.reverse -- [ 3, 2, 1 ]
|> List.head -- Just 3
else
Nothing
Конечно, вы получаете Maybe, и вам нужно разворачивать его, когда вы используете эту функцию. Нет гарантии, что ваш список не будет пустым или вы попросите уникальный индекс (например, 1000), так что почему коммандер elm заставляет вас учитывать этот случай.
main =
let
fifthElement =
case 5 !! [1,2,3,4,255,6] of // not sure how would you use it in Haskell?! But look nice as infix function. (inspired by @Daniël Heres)
Just a ->
a
Nothing ->
-1
in
div []
[ text <| toString fifthElement ] // 255