Why does this Haskell code work successfully with infinite lists?

Let’s do a little trace in our heads of how Haskell will evaluate your expression. Substituting equals for equals on each line, the expression pretty quickly evaluates to True:

myAny even [1..]
foldr step False [1..]
step 1 (foldr step False [2..])
even 1 || (foldr step False [2..])
False  || (foldr step False [2..])
foldr step False [2..]
step 2 (foldr step False [3..])
even 2 || (foldr step False [3..])
True   || (foldr step false [3..])
True

This works because acc is passed as an unevaluated thunk (lazy evaluation), but also because the || function is strict in its first argument.

So this terminates:

True || and (repeat True)

But this does not:

and (repeat True) || True

Look at the definition of || to see why this is the case:

True  || _ =  True
False || x =  x

Leave a Comment

tech