[Haskell-cafe] How to write fast for loops

Daniel Fischer daniel.is.fischer at googlemail.com
Sun Apr 27 02:12:55 UTC 2014

On Sunday 27 April 2014, 02:46:07, Niklas Hambüchen wrote:
> Thanks for the insight! There's one thing I don't understand yet:
> On 27/04/14 02:32, Daniel Fischer wrote:
> > The problem is that you use the same list multiple times, and GHC thinks
> > "hey, let me re-use that", so it gets floated to the top-level, and the
> > inner "loop" really uses the list, which apart from the `case`s on the
> > list forces it to use boxed 'Int's instead of Int#. Then the boxed Ints
> > need to be unboxed to be used, oops.
> When you say that the problem is that I "use the same list multiple
> times", do you mean that I use the actual syntactic expression
> `[0.._SIZE-1]` multiple times on multiple lines, and suggest that this
> should not happen if I use it in only one place?

More or less. The `_SIZE - 1` is constant-folded to 511, so writing the list 
as [0 .. 511] would probably not prevent the sharing. And using the same list 
in a different function may or may not affect the produced code, I don't know 
GHC well enough to predict that.

If you write it in a form that GHC doesn't recognise as the same value, GHC 
can and does optimise it as if the value were used only once.

> If so, how far does that go, and would GHC even notice that it is the
> same as a potential `[0.._511]` I might write elsewhere?

Depends on "elsewhere". I've seen GHC produce multiple top-level values for 
the very same thing used in different functions in the same module, so if 
"elsewhere" means a different function and inlining doesn't cause GHC to see 
the two at the same time, it will probably not notice. But ask somebody who 
knows how GHC works if you want to be sure.

> > Do the idiomatic thing and write a loop ;)
> Unfortunately, `forM_ [1..n]` is pretty much the most idiomatic and
> beautiful way I can come up with when ask for an iteration over 1 up to
> n!

Well, my idiom is looping, because.

> So this better be fixed :)


More information about the Haskell-Cafe mailing list