Flipped versions of folds are better when we need to define the fold inline.
primes :: MonadIO m => Fold m Int (MutArray Int)
primes =
flip Fold.foldlM' (pure MutArray.empty)
$ \arr n -> do
isPrime <-
Stream.fold (Fold.all (\p -> n `mod` p /= 0))
$ Stream.takeWhile (\p -> p * p <= n)
$ MutArray.read arr
if isPrime
then MutArray.snoc arr n
else pure arr
We can call the flipped version as foldWith. We can also add a termination condition, which makes it more like a familiar for loop.
The applies to scans as well.