I want to write a function that goes through a list updating an accumulator until that accumulator reaches a certain condition or I get to the end of the list. For example, a product function that stops as soon as its accumulator reaches zero.
I know how to code it by writing the recursion by hand:
{-# LANGUAGE BangPatterns #-}
prod :: [Integer] -> Integer
prod xs =
go 1 xs
where
go 0 _ = 0
go !acc [] = acc
go !acc (x:xs) = go (acc * x) xs
but is there a way to code this using folds and other higher order functions?
One thing that comes to mind is defining
mult 0 _ = 0
mult x y = x * y
and then using foldl'. However, this doesn't break out early so its a bit wasteful of performance.
We can't use foldr since it goes through the list in the wrong order and its way of "breaking out early" is by looking at the elements of the list instead of looking at the accumulator (this would have mattered if the accumulator had a different type than the list elements).