Are variables in list comprehensions immutable?
[x + 1 | x <- [1,2,3,4,5]]
For instance, in the above example, x
seems to change it's value. Is this what is really happening, or is something more complicated at work here?
There are no variables in Haskell, only values bound to names.
What a list comprehension like this will get turned into is actually monadic list code:
y = [x + 1 | x <- [1, 2, 3, 4, 5]]
y = do
x <- [1, 2, 3, 4, 5]
return (x + 1)
Then this further gets reduced to using >>=
:
y = [1, 2, 3, 4, 5] >>= (\x -> return (x + 1))
And then we can look at the definition for the Monad
instance for []
:
instance Monad [] where
return x = [x]
list >>= f = concat (map f list)
-- uses the `concatMap` function in the actual definition
-- where `concatMap f list = concat (map f list)`
So replacing return
:
y = [1, 2, 3, 4, 5] >>= (\x -> [x + 1])
And then >>=
:
y = concat (map (\x -> [x + 1]) [1, 2, 3, 4, 5])
Now we can reduce it:
y = concat [[1 + 1], [2 + 1], [3 + 1], [4 + 1], [5 + 1]]
y = concat [[2], [3], [4], [5], [6]]
y = [2, 3, 4, 5, 6]
So as you can see, it's not that x
is a variable that changes values, x
becomes the argument to a lambda function that is then mapped across the target list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With