Problem with eta expansion

Manuel M. T. Chakravarty chak@cse.unsw.edu.au
Sat, 03 Mar 2001 16:44:35 +1100


For a change, another eta expansion problem.  Given

  fact 0 = 1
  fact n = n * fact (n - 1)

  foo x = let y = fact x
	  in
	  if y == x
	  then 
	    print y
	  else do
	    print $ y + x
	    foo x

  main = foo 10

compiled with the HEAD from yesterday night using

  ghc -O2 -c EtaState.hs -ddump-simpl -no-recomp

I get

  Main.$wfoo
    = \ w :: PrelNum.Integer ->
	let {
	  y :: PrelNum.Integer
	  __A 0 __C
	  y = fact w
	} in 
	  case PrelNum.a8 y w of wild {
	    PrelBase.True ->
	      \ w1 :: (PrelGHC.State# PrelGHC.RealWorld) ->
		case PrelIO.$whPutStr
		       PrelHandle.stdout
		       (PrelNum.showsPrec
			  PrelBase.zeroInt y (PrelBase.$w[] @ PrelBase.Char))
		       w1
		of wild1 { (# new_s, a11 #) ->
		PrelIO.$whPutChar PrelHandle.stdout '\n' new_s
		};
	    PrelBase.False ->
	      \ w1 :: (PrelGHC.State# PrelGHC.RealWorld) ->
		case PrelIO.$whPutStr
		       PrelHandle.stdout
		       (PrelNum.showsPrec
			  PrelBase.zeroInt
			  (PrelNum.plusInteger y w)
			  (PrelBase.$w[] @ PrelBase.Char))
		       w1
		of wild1 { (# new_s, a11 #) ->
		case PrelIO.$whPutChar PrelHandle.stdout '\n' new_s
		of wild2 { (# new_s1, a1 #) ->
		Main.$wfoo w new_s1
		}
		}
	  }
  end Rec }

As GHC doesn't pull the two abstractions out of the case
alternatives, it misses out on other optimisations like
LiberateCase in some code in the array library.

Cheers,
Manuel