Add foldr' and document the laziness of foldr #436
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Unlike for lists,
foldr'
is a useful primitive for strictText
since we can easily iterate from either end. I discovered that while working on the other PR aboutstatefulSpan
, which usesfoldr'
in a test. It also turns out thatfoldr
is lazier than one might expect, thanks to its implementation via a lazy stream, rather than an eager imperative loop, so that seemed worth documenting.foldr
andfoldr'
are thus mostly equivalent denotationally, ignoring the strictness differences, but operationally,foldr
starts executing from the left, whilefoldr'
starts from the right.foldr
can short-circuit, whereasfoldr'
has to traverse the whole list, but can do so in a tighter loop.foldr'
can also be defined for lazyText
but it's a little more involved.foldl
can also be made lazier than it is currently, by starting from the right end (and this is arguably evidence thatfoldr
's aforementioned laziness is not that obvious from a certain perspective), but because that's an existing function I will need a more careful look to be sure I'm not breaking anything. Hence I'm postponing that for a future PR.Note: this idea is already present in bytestring https://github.com/haskell/bytestring/blob/master/Data/ByteString.hs#L558