Why doesn't GHC do the following optimisation?

Simon Peyton-Jones simonpj at microsoft.com
Thu Nov 13 09:14:46 EST 2003


It's a while since I paid serious attention to making sure that GHC's
transformations are all working right.  Things are usually more
complicated than one might hope.

In this case, 
* foldl is defined in the prelude using explicit recursion, as it
happens

* you've defined foldl' using foldr, and that has the potential to do
list fusion
	with the [1..n]

* but you've exported sum2, so the inlining doesn't happen.  If you keep
sum2 private
	module Main( main ) ...
   you'll see quite different code

* there's an awkwardness with eta-expanding foldl, which I have never
fully
	dealt with -- needs a kind of analysis.  It's described in 3.2.3
of Gill's thesis
	(see also 4.4).  http://www.cse.ogi.edu/~andy/

I wish it were all more predictable!

Simon

| -----Original Message-----
| From: haskell-cafe-bounces at haskell.org
[mailto:haskell-cafe-bounces at haskell.org] On Behalf Of
| andrew cooke
| Sent: 12 November 2003 17:40
| To: haskell-cafe at haskell.org
| Subject: Why doesn't GHC do the following optimisation?
| 
| 
| Hi,
| 
| This question is purely out of curiousity - I'm no expert on this.  I
| wrote the following code:
| 
| sum1 :: [Int] -> Int
| sum1 = foldl (+) 0
| 
| foldl' :: (a -> b -> a) -> a -> [b] -> a
| foldl' f v l = foldr (\x -> \fld -> \v' -> fld $ f v' x) id l v
| 
| sum2 :: [Int] -> Int
| sum2 = foldl' (+) 0
| 
| main :: IO ()
| main = do n <- readLn;
|           print $ sum1 [1..n];
|           print $ sum2 [1..n]
| 
| and ran it through ghc with: ghc Folds.hs -ddump-simpl -O
| 
| I was expecting the two calls to be optimized to something equivalent,
or
| even for the result of a single calculation to be printed twice.
However,
| peering at the Core output, it seems that the two sum functions exist
| separately and have different structure (sum1 appears to have a simple
| recursive definition, while sum2 involves two lamba expressions).
| 
| I did all this because I read a paper introducing folds that showed
how
| you can express foldl in terms of foldr and giving the derivation.
| Unfortunately I don't have the paper/derivation, but I believe my
foldl'
| is correct (that may be the problem, of course - that sum1 and sum2
are
| not equivalent either because of a coding error, or because of some
| subtlety in the types, although I carefully gave them explicit types
to
| try and avoid that).
| 
| The derivation wasn't that complicated (althugh I find it simpler to
| simply write the fold down).  If it's not an error on my part, why
doesn't
| ghc do the same kind of transformation itself?  Or am  mistaken in
| thinking that if derivation is easy then the revrese transformation as
an
| optimisation should also be easy?
| 
| Thanks,
| Andrew
| 
| --
| http://www.acooke.org/andrew
| _______________________________________________
| Haskell-Cafe mailing list
| Haskell-Cafe at haskell.org
| http://www.haskell.org/mailman/listinfo/haskell-cafe




More information about the Haskell-Cafe mailing list