I am studying Haskell and I have the following expression on the Haskell Wiki that really puzzled me:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
I can’t understand why this is working.
If I use the standard logic Currying (zipWith (+)) , it returns a function that takes a list as an argument and, in turn, returns another function that takes a different list as an argument and returns a list ( zipWith::(a -> b -> c) -> [a] -> [b] -> [c] ). Thus, fibs is a link to a list (which has not yet been rated), and (tail fibs) is the tail of the same (unvalued) list. When we try to evaluate ( take 10 fibs ), the first two elements are tied to 0 and 1 . In other words, fibs==[0,1,?,?...] and (tail fibs)==[1,?,?,?] . After the first addition is complete, fibs becomes [0,1,0+1,?,..] . Similarly, after the second addition we get [0,1,0+1,1+(0+1),?,?..]
- Is my logic correct?
- Is there an easier way to explain this? (any ideas from people who know what the Haskell complier does with this code?) (links and links are welcome)
- True, this type of code only works because of lazy evaluation?
- What grades happen when I do
fibs !! 4 fibs !! 4 ? - Does this code mean that zipWith processes the elements first? (I think this should not be, but I do not understand why not)
EDIT2: I just found the above question and answered here . I'm sorry if I wasted any time.
EDIT: here is a more complicated case to understand (source: Project Euler forums ):
filterAbort :: (a -> Bool) -> [a] -> [a] filterAbort p (x:xs) = if px then x : filterAbort p xs else [] main :: Int main = primelist !! 10000 where primelist = 2 : 3 : 5 : [ x | x <- [7..], odd x, all (\y -> x `mod` y /= 0) (filterAbort (<= (ceiling (sqrt (fromIntegral x)))) primelist) ]
Note that all (\y -> x mod y /= 0)... How can I refer to x here DO NOT call infinite recursion?
recursion haskell lazy-evaluation self-reference
Vladimir Bychkovsky
source share