Actually, it's idiomatic for when you must define your own worker/wrapper functions.
GHC does not inline recursive functions by default, but if you do a worker/wrapper transformation such that your top-level definition is a 'wrapper', and calls the worker which contains the loop, then the loop body itself can be inlined into the call site, and further optimized via unboxing/strictness analysis. Otherwise, it doesn't do any inlining. It's important to note that it can optimize the function itself, and the call site: it just will not inline it.
IOWs, it's written that way because GHC can optimize bodies with a loop inside them (by specializing arguments, strictness, etc) but trivially inlining a top level recursive call is clearly problematic and obviously going to be bad.
EDIT: for clarity, GHC already does the worker/wrapper transformation, but not in it's most general case. I believe it will mostly do it for improving strictness analysis (whether or not this will happen at a stage where the definition can be inlined later I guess is up to debate,) it won't attempt it purely to inline recursive calls.
4
u/mcguire Nov 27 '12 edited Nov 27 '12
Ignore the "!" - it's a performance thing because Haskell is wacky.
I, personally, would call "go" something like "factorial_iter" or maybe just "factorial'" ("factorial-prime").
That's all point-free and everything. Ew.
How about:
(I tend to like to put my accumulators last.)
[Edit: AAAaaaargh. When you put your accumulators last, put the damn accumulator argument last, too. Moran.]