Skip to content

Add mapAccumL'#22

Merged
Bodigrim merged 6 commits intoBodigrim:masterfrom
Daniel-Diaz:master
May 12, 2025
Merged

Add mapAccumL'#22
Bodigrim merged 6 commits intoBodigrim:masterfrom
Daniel-Diaz:master

Conversation

@Daniel-Diaz
Copy link
Contributor

A strict version of mapAccumL.

Motivation

I was getting

*** Exception: stack overflow

when querying for values very deep into the result of mapAccumL.

Solution

Once I switched to use the function added by this PR, it worked fine.

Thank you.


-- | Same as 'mapAccumL', but strict in accumulator.
mapAccumL' :: (acc -> x -> (acc, y)) -> acc -> Infinite x -> Infinite y
mapAccumL' f = go
Copy link
Owner

Choose a reason for hiding this comment

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

Could it be expressed via foldr or other high-level combinator? Could there be rewrite rules for fusion similar to mapAccumLFB?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll take a look.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Bodigrim

I wrote mapAccumL' following the definition for mapAccumL, and simply adding bang patterns on the accumulator. This works (not getting stack overflows, at least for now), but this benchmark shows the foldr version taking ~15% longer when I run it. I don't know whether I'm doing something wrong.

Copy link
Owner

Choose a reason for hiding this comment

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

The benchmark gives the same numbers on my machine, at least with GHC 9.10.2:

benchmarking mapAccumL/mapAccumL1
time                 30.84 μs   (30.80 μs .. 30.91 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 30.89 μs   (30.84 μs .. 30.96 μs)
std dev              181.4 ns   (141.0 ns .. 232.0 ns)

benchmarking mapAccumL/mapAccumL2
time                 30.95 μs   (30.88 μs .. 31.04 μs)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 31.04 μs   (30.90 μs .. 31.38 μs)
std dev              646.1 ns   (180.1 ns .. 1.155 μs)
variance introduced by outliers: 18% (moderately inflated)

So let's proceed with the foldr version.

Could you please add tests, both to Properties.hs and Fusion.hs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. That's good to know. I was using ghc-9.8.4. I'll see to add those tests later today.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Bodigrim

Tests added in 90e40ab.

@Bodigrim Bodigrim merged commit fcce912 into Bodigrim:master May 12, 2025
13 checks passed
@Bodigrim
Copy link
Owner

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants