Since I realized my code was always using infinite lists, I replaced it by Data.Stream.

However, my code stopped working.

The problem is with these functions:
scan :: (a -> b -> a) -> a -> Stream b -> Stream a
scan f z (Cons x xs) =  z <:> scan f (f z x) xs

-- | @scan'@ is a strict scan.
scan' :: (a -> b -> a) -> a -> Stream b -> Stream a
scan' f z (Cons x xs) =  z <:> (scan' f $! (f z x)) xs
They are too strict I think. My code works again when I add a lazy pattern match:

scan f z ~(Cons x xs) = z <:> scan f (f z x) xs
scan' f z ~(Cons x xs) =  z <:> (scan' f $! (f z x)) xs
This is justified since they then behave like scanl on lists. However it seems this package is used a lot, so maybe some code depends on this strictness.

What to do?

PS: Why does scanl' not exist in Data.List?