How does one fold over a monad strictly? Data.Foldable
has the strict foldl'
and the monadic foldlM
, but no strict foldlM'
? Is the strictness somehow defined by the monad itself? If so, how does one work out what it is?
Imagine I must determine whether the product of an enormous list of ring elements is zero, but my ring isn't an integral domain, i.e. it contains zero devisors. In this case, I should tail recursively foldl
my multiplication ***
over the list, but return False
the moment the product becomes zero, rather than waiting on the full product.
safelist :: [p] -> Bool
safelist [] = True
safelist (x:xs) = snd $ foldl' f (x,True) xs
where f (u,b) v = (w, b && w /= Zero) where w = u *** v
I could perhaps simplify this code slightly using the Maybe
monad's foldlM
but doing so seemingly lacks the required strictness.