jonascarpay / apecs

a fast, extensible, type driven Haskell ECS framework for games
391 stars 43 forks source link

lazy cfoldr and cfoldMap #91

Open ramirez7 opened 2 years ago

ramirez7 commented 2 years ago

cfold is strict in its accumulator, which means you cannot short-circuit. A lazy cfoldr and cfoldMap (based on unboxed vector equivalents) would allow for this. The Any and All are practical examples of this laziness's usefulness.

jonascarpay commented 2 years ago

Because reading a component is monadic, cfold is (like foldM) necessarily a left-fold. That means we can't get short-circuit laziness the way we can with foldr. I agree that a lazy fold would be useful, but I'm not sure what that would look like, or what a good type for it would be. Do you have any suggestions?

dpwiz commented 2 years ago

cfold is (like foldM) necessarily a left-fold.

That's a bit more complicated...

foldM = foldlM

but:

The monadic effects of foldlM are sequenced from left to right.

If at some step the bind operator (>>=) short-circuits (as with, e.g., mzero in a MonadPlus), the evaluated effects will be from an initial segment of the element sequence.

If you want to evaluate the monadic effects in right-to-left order, or perhaps be able to short-circuit after processing a tail of the sequence of elements, you'll need to use foldrM instead.

And it is actually foldr inside. It is foldrM that is implemented with foldl.