Anyone familiar with Haskell will have likely seen this implementation of the Fibonacci sequence.
fibs = 0:1:zipWith (+) fibs (tail fibs)
The way I understand this is as follows:
- Haskell's lazy evaluation allows for this infinite recursion with no issues
- The way Haskell constructs lists (pairing the first element with the rest of the list) means the zipWith is evaluated to obtain the next element when needed
- When
fibsis referenced in the zipWith parameters, it takes the list as it currently exists without the new element being evaluated
With that knowledge, why does this loop infinitely rather than generate a list of primes?
main = print $ take 10 primes
dividesNone x ys = not $ any ((==0) . (x `mod`)) ys
primes = 2:[x | x <- [2..], x `dividesNone` primes]
I've tried similar implementations using dropWhile and find but the same thing happens. I've settled on this one as the one I most think "should" work. I'm sure there is some way to make this work the way I want - but even if I knew what that way was, I wouldn't understand why this doesn't. What is the difference between these two examples that causes one to work and one to loop infinitely?