How do I access a list element I've added with the cons (:) operator?
Asked Answered
L

4

7

I'm new to Haskell (and functional programming in general) and was wondering how I can access a new element that I've added to a list using the cons (:) operator?

For example, using WinGHCi I create a new list and access the first element:

ghci> let a = [1,2,3]
ghci> a!!0
1

The prompt returns 1, the value of the first element, cool. Now I append a new value to the front of the list and try to access it:

ghci> 5:a
[5,1,2,3]
ghci> a!!0
1

It looks like the list items don't get re-indexed. I tried getting a negative index to work and other such things but the compiler didn't seem to approve. The tutorials I'm reading just skip over it and I couldn't find anything of use online. How do I get the value "5" from the list?

Thanks for the help and sorry if this is a very basic question.

Lyrebird answered 28/2, 2012 at 17:33 Comment(4)
To illustrate Marcin's point, type 'a' at GHCI and you'll see [1,2,3], because you cannot modify a variable in Haskell. To clarify things, consider these definitions of variable and assignable: Haskell has 'variables' in the math sense, but not 'assignables' as in imperative languages.Intend
a is still [1,2,3] after 5:a.Thera are no side effects like mutation in functional programmingOvershine
Ya I get it now, it's just a whole other of thinking... haha. Thanks everyone!Lyrebird
Haskell has immutable data. Variables don't exist - only static values with the name variables exist. This is indeed a very basic question about the bare basic concepts within Haskell.Statistical
C
12

This idea lies at the core of functional programming: you are (usually) not modifying data in place. So you don't add an item to a list: you create a new list without modifying the old one.

This allows for many nice things, sharing for instance, because you are never changing the old data and so you can keep referring to it. But it also imposes a burden if you are accustomed to other programming paradigms: you have to change your way to approach things (and often you have to change your data structures/algorithms because they were relying on in-place modification of a data structure).

In your example, just give a new name to the cons'ed list:

let a = [1, 2, 3]
let b = 5:a
Checkerberry answered 28/2, 2012 at 17:41 Comment(0)
N
7

Your misunderstanding is fundamental: cons does not destructively modify anything.

5:a (where a = [1,2,3]) evaluates to [5,1,2,3], and that is what the interpreter is showing you.

Nonetheless answered 28/2, 2012 at 17:37 Comment(0)
M
6

Let me illustrate with (+) as well as (:)

Prelude> 4+5
9
Prelude> let z = 5
Prelude> z
5
Prelude> 4+z
9
Prelude> z
5
Prelude> let y = 4+z
Prelude> y
9
Prelude> z
5

versus

Prelude> let a = [1,2,3]
Prelude> a
[1,2,3]
Prelude> 5:a
[5,1,2,3]
Prelude> a
[1,2,3]
Prelude> let b = 5:a
Prelude> b
[5,1,2,3]
Prelude> a
[1,2,3]

Bindings made with 'let' never change, but new ones can be made. If a new binding has the same name as an old binding then the old binding is "shadowed" not mutated.

Misjudge answered 28/2, 2012 at 17:56 Comment(0)
Q
2

Lists are immutable:

Prelude> let xs = [1,2,3]
Prelude> 4:xs
[4,1,2,3]
Prelude> xs
[1,2,3]
Prelude> let ys = 4:xs
Prelude> ys
[4,1,2,3]

If you wanna change the elements of the data structure use Arrays.

Quiche answered 28/2, 2012 at 17:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.