
Don Stewart wrote:
You'd want a general fusion framework for this, and other accumulators, that's let's you treat 'f' as a zip of some kind that pulls items from its two arguments. And then require only a single rewrite rule for all your loop forms.
Stream fusion (see "Lists to Streams to Nothing at All") at least does this for zips,
zip (foldl .. ) (foldl .. )
Will end up with a single loop, but for an arbitrary 'f' instead of zip, seems harder.
It seems the thing to do would be to expose a top-level function for explicitly specifying that this is what you want to do: foo :: (x' -> y' -> z') -> ([x] -> x') -> ([y] -> y') -> [x] -> [y] -> z' You could then say mean xs = foo (/) sum length which is pretty declarative, and gives the compiler an easy time with optimising. Of course, if nobody chooses to *use* this function... it won't help you any.