In Haskell I can write a self referential sequence, in GHCI, like so:
λ> let x = 1:map (+1) x
λ> take 5 x
which produces:
[1,2,3,4,5]
However my intuition on lazy evaluation says this should happen during expansion
let x = 1:map (+1) x
1:2:map (+1) x
1:2:map (+1) [1, 2] <-- substitution
1:2:2:3:map (+1) x
1:2:2:3:map (+1) [1, 2, 2, 3] <-- substitution
1:2:2:3:2:3:3:4:map (+1) x
...
This is obviously not what's happening. I can see the pattern in the correct answer. We are merely moving one element in the list at a time down an infinite stream. The pattern I recognize and I can apply it in code. However it does not line up with my mental model of lazy evaluation. It feels a bit "magic". Where is my intuition wrong?