On Wed, 4 Jun 2008, Duncan Coutts wrote:

On Wed, 2008-06-04 at 09:32 +0200, Henning Thielemann wrote:

Now the difficult question: How to write the 'mean' function in terms of
'sum' and 'length' while getting the same performance?

There's another rather harder fusion transformation that notices when
two left folds are demanded in the same strictness context and they fold
over the same input list then they can be performed together.

sum    = foldl (\s x -> s + x) 0
length = foldl (\l x -> l + 1) 0

mean xs = sum xs / length xs

So we must note that sum and length are demanded at the same time and
since they are both foldl's will consume the whole of xs.

So we can merge the two foldl's into one just by tupling them up:

sumlength = foldl (\(s, l) x -> (s + x, l + 1)) (0, 0)

mean xs = s / l
 where (s, l) = sumlength xs


How about assisting the compiler with a helper function named 'parallel' ?

parallel :: ([a] -> b, [a] -> c) -> [a] -> (b,c)
parallel (f,g) xs = (f xs, g xs)

mean xs =
  uncurry (/) $ parallel (sum,length) xs


? We could state RULES in terms of 'parallel'. By calling 'parallel', the user tells, that he wants fusion here.

Say
  "parallel/foldl/foldl" forall f, g, x0, y0.
      parallel (foldl f x0, foldl g y0) = foldl (\(x,y) z -> (f x z, g y z)) 
(x0,y0)
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to