все, как только создалось значение Cons x (foldr f z xs)
дальше ничего вычисляться не будет
потом мы можем заматчить результат
let x = Cons x (foldr f z xs)
h x =
case x of
-- в этот момент вычисляется конструктор x, чтобы проверить, это Nil или Cons
Nil -> pure ()
Cons x xs -> do
-- в этот моменте он значет что конструктор Cons, но x и xs не вычислены еще
print x
-- после этого момента он уже вычислил x, но xs все еще нет
if x < 10 then h xs else pure ()
-- на следующей итерации он уже вычислит xs, но вычислит список ровно настолько, насколько нужно, на первом же элементе >= 10 он прекратит вычлять список, какой бы длины он не был