Skip to content

Strict version of `foldlM`.

Data.Foldable.foldlM is lazy on the accumulation parameter.

A user can define foldlM (\acc x -> acc seq step acc x) z xs, but actually this function is NOT strict! It is simplified to the following core:

foldlM (\acc x -> acc `seq` step acc x) z xs
 ==
go xs z where
  go [] acc = pure acc
  go (x:xs) acc = (acc `seq` step acc x) >>= go xs

DemandAnalysis infers that go is lazy on the second argument because pure is lazy in general (e.g. IO Monad).

Thus foldlM' is needed.

Its definition would be:

foldlM' :: (Monad m, Foldable t) => (b -> a -> m b) -> b -> t a -> m b
foldlM' f z0 xs = foldr c (\x -> x `seq` pure x) xs z0
  where c x k = \z -> z `seq` (f z x >>= k)
        {-# INLINE c #-}
Trac metadata
Trac field Value
Version 8.6.3
Type FeatureRequest
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information