Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are variables in list comprehensions immutable?

Tags:

haskell

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?

like image 461
flyingfisch Avatar asked Jan 09 '23 17:01

flyingfisch


1 Answers

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.

like image 67
bheklilr Avatar answered Jan 18 '23 08:01

bheklilr