I got a list, and now I want the nth item. In Haskell I would use !!
, but I can't find an elm variant of that.
3 Answers
Elm added arrays in 0.12.1, and the implementation was massively overhauled in 0.19 to improve correctness and performance.
import Array
myArray = Array.fromList [1..5]
myItem = Array.get 2 myArray
Arrays are zero-indexed. Negative indices are not supported currently (bummer, I know).
Note that myItem : Maybe Int
. Elm does everything it can to avoid runtime errors, so out of bounds access returns an explicit Nothing
.
If you find yourself looking to index into a list rather than take the head and tail, you should consider using an array.

- 6,189
- 4
- 39
- 41
-
1`negativeGet index array = get (index + length array) array` – Alex Shroyer Mar 08 '16 at 16:18
-
Does the last line still hold true in light of https://github.com/elm-lang/core/issues/649 ? – KillerX Sep 29 '17 at 08:22
-
The fixed array implementation has been merged but not released. – mgold Oct 08 '17 at 21:02
-
Confirm. Latest release 5.1.1 is from 2017-01-23 https://github.com/elm-lang/core/releases and Skinney commited on 2017-04-02 https://github.com/elm-lang/core/commit/4213c610b3ecb4b856e09b6b07577d06c0e3dfef#diff-67a364ff7fde87ebc2f09ac1c9ad0680 – rofrol May 03 '18 at 09:23
-
You could make this support both positive and negative indices by `mod`ing the index by the length of the array. – Apr 17 '21 at 15:48
There is no equivalent of this in Elm. You could of course implement it yourself.
(Note: This is not a "total" function, so it creates an exception when the index is out of range).
infixl 9 !!
(!!) : [a] -> Int -> a
xs !! n = head (drop n xs)
A better way would be to define a total function, using the Maybe data type.
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)

- 243
- 2
- 4
-
Just to add another alternative (last (take index list) -> works only if index is not 0 or 1 but you get the idea. – Jeremy D Apr 27 '14 at 10:53
-
Haskell raises an out of range exception when you use (!!) out of range. I guess it would make sense to use Maybe but it seems odd to request an element from a list and get something of a type that's not the type of the elements in the list (in this case getting Maybe a instead of a) – Hassan Hayat Apr 29 '14 at 22:53
-
11In more recent versions of Elm, you can define `get n xs = List.head (List.drop n xs)` and it's a total function, done. The `|` syntax above was removed in 0.16. – mgold Dec 13 '15 at 19:42
I've used this:
(!!): 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
Of course you get a Maybe and you need to unwrap it when you use this function. There is not guarantee that your list will not be empty, or that you ask for a imposible index (like 1000) - so that's why elm compiler forces you to account for that case.
main =
let
fifthElement =
case 5 !! [1,2,3,4,255,6] of // not sure how would you use it in Haskell?! But look's nice as infix function. (inspired by @Daniël Heres)
Just a ->
a
Nothing ->
-1
in
div []
[ text <| toString fifthElement ] // 255

- 12,521
- 10
- 47
- 73