Volk64
Volk64

Reputation: 33

Returning a list element using positions

I have recently taken upon myself to learn Haskell and, in one of the first lessons, I have been told to learn how to manipulate lists first. I understand how to pick a list element from it's position like this

    myList = [7, 3, 6, 15, 8]
    myList !! 3

Now, I would want to know if it's possible to pick a position starting from the last element of the list, just like what I have been doing in Python using this

    pythonlist = [7, 3, 6, 15, 8]
    pythonlist[-2]

Upvotes: 0

Views: 111

Answers (3)

Jeremy D
Jeremy D

Reputation: 4855

You can do :

(!!<) :: [a] -> Int -> a 
l !!< i = (reverse l) !! i

But it means you cannot use negative numbers, only a positive index, but it will look from the end of the list.

Or if you really wanna use negatives:

(!!<) :: [a] -> Int -> a
l !!< i = if i < 0 then l !! (length l + i) else l !! i

Upvotes: 1

crockeea
crockeea

Reputation: 21811

In certain cases, yes. You can simply redefine (!!) to:

xs !! i | i >= 0 = xs Data.List.!! i
        | i < 0 = let n = length xs
                  in xs Data.List.!! (n+i)

However, this isn't really a great idea in Haskell due to laziness. The solution above works on finite lists, which is what you are talking about in Python. Consider what happens on an infinite list, however: [1..] !! (-2). We first evaluate length [1..], which never terminates! The problem is that you can't index from the end of an infinite list.

Upvotes: 0

leftaroundabout
leftaroundabout

Reputation: 120751

First off, if you find yourself accesing lists by index (which you shouldn't often do anyway, it's inefficient and ugly: prefer functional tools such as folds, map, and the monad instance) then you should better switch to some array data type, e.g. Vector.

But sure enough it's possible to access lists by index, also from the back:

(!!<) :: [a] -> Int -> a
l !!< i = l !! i'
 where i' = length l - i - 1

I hope it's obvious enough how this works. It's even more inefficient than ordinary access because length traverses the entire list, but there you are.

Upvotes: 1

Related Questions