Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add foldr' and document the laziness of foldr #436

Merged
merged 1 commit into from
May 17, 2022

Conversation

Lysxia
Copy link
Contributor

@Lysxia Lysxia commented May 16, 2022

Unlike for lists, foldr' is a useful primitive for strict Text since we can easily iterate from either end. I discovered that while working on the other PR about statefulSpan, which uses foldr' in a test. It also turns out that foldr 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 and foldr' are thus mostly equivalent denotationally, ignoring the strictness differences, but operationally, foldr starts executing from the left, while foldr' starts from the right. foldr can short-circuit, whereas foldr' has to traverse the whole list, but can do so in a tighter loop.

  • foldr' can also be defined for lazy Text but it's a little more involved.
  • Dually, foldl can also be made lazier than it is currently, by starting from the right end (and this is arguably evidence that foldr'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

Copy link
Contributor

@Bodigrim Bodigrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to add a test, which witnesses the difference between foldr and foldr'? E. g., use f which explodes with an error on certain chars and a carefully crafted Text.

@Lysxia
Copy link
Contributor Author

Lysxia commented May 16, 2022

I added a test to distinguish foldr from foldr' and also foldl/foldl'.

I could also test for the memory usage of foldr', with a basic example foldr' (+) 0 on a long text with a restricted stack/heap. I have a working prototype but I'm not sure of the best way to include it in the repo. Is it worth a separate test suite with its own RTS options, or is there a better alternative?

@Bodigrim Bodigrim merged commit 3649ea9 into haskell:master May 17, 2022
@Lysxia Lysxia deleted the foldr-strict branch May 17, 2022 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants