Implement Applicative based API #522
Draft
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.
Implementation follows plan described in #477 with
generateA :: Applicative f => Int -> (Int -> f a) -> f (v a)
as primitive. It is not subject to stream fusion.Writing
generateA
is not difficult. Problem is doing it efficiently. Current benchmarks are (suggestions for more are very welcome):First and naive implementation uses list as intermediate data structure. Sum benchmark performs well in this case. Using
STA
instead brings map benchmark on par with explicit loop and produces slight (5-10%) improvements in state and IO benchmark)Currently sum and map perform on par with explicit loop. State gives 7x slowdown and 8x allocations, IO benchmark 4x slowdown and 8x allocations. We obviously can add rewrite rules for
IO
/ST
but maybe there're more general optimizations.Fixes #477, #69, #132, #144