I am quite new to Haskell and I'm trying to wrap my head around how the lazy expression of Fibonacci sequences work.
I know this has been asked before, but none of the answers have addressed an issue I'm having with visualising the result.
The code is the canonical one using zipWith
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
I understand the following:
zipWith
literally zips two lists togethertail
grabs all but the first element of a list- Haskell references 'to-be' computed data as
thunks
.
From my understanding, it first adds [0,1,<thunk>]
and [1,<thunk>]
using zipWith (+)
to give [1,<thunk>]
. So now you have
fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs)
A lot of references I've Googled have then proceeded to "visualise" the line above as
fibs = 0 : 1 : 1 : zipWith (+) [1,1,<thunk>] ([1,<thunk>]).
My question is this:
Why is the fibs
component in the line above only corresponding to [1,1,<thunk>]
instead of [0,1,1,<thunk>]
?
Shouldn't fibs
contain the entire list plus <thunk>
?
take 3 fibs
). That way there's no confusion between same piece of data accessed twice (through the same name), or two equal pieces of data (each having its own name). – Doironfibs = 0 : 1 : 1 : zipWith (+) (drop 1 $ fibs) (drop 1 $ tail fibs)
, because at this point we have advanced one notch along the list. and therein lies the answer to your question. – Doiron