id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	os	architecture	failure	difficulty	testcase	blockedby	blocking	related
4830	Simplifier does case-to-let too eagerly	simonpj		"Roman found an example where the simplifier was turning a case expression to a let binding when it shouldn't
{{{
foo :: Int -> Maybe (Double,Double) -> Double 
foo _  Nothing     = 0 
foo 0 (Just (x,y)) = x+y 
foo n (Just (x,y)) = let r = f x y in r `seq` foo (n-1) (Just r)
  where
    f x y | x <= y    = (x,y)
          | otherwise = (y,x)
}}}
GHC 7.0.1 generates this
{{{
foo =
  \ (ds_dks :: Int) (ds_dkt :: Maybe (Double, Double)) ->
    case ds_dkt of _ {
      Nothing -> lvl_sly;
      Just ipv_skO ->
        case ds_dks of _ { I# ds_dku ->
        case ds_dku of ds_XkC {
          __DEFAULT ->
            case ipv_skO of _ { (x_aax, y_aay) ->
            case x_aax of wild_akY { D# x_al0 ->
            case y_aay of wild1_al2 { D# y_al4 ->
            foo
              (I# (-# ds_XkC 1))
              (Just
                 @ (Double, Double)
                 (case <=## x_al0 y_al4 of _ {
                    False -> (wild1_al2, wild_akY); True -> (wild_akY, wild1_al2)
                  }))
            }
            }
            };
          0 -> case ipv_skO of _ { (x_aau, y_aav) -> plusDouble x_aau y_aav }
        }
        }
    }
}}}
That `<=##` should be outside the call to `foo` not inside. (The code isn't wrong, it's just less efficient than it should be.)

I know what's wrong.  Patch coming."	bug	closed	normal		Compiler	7.0.1	fixed			Unknown/Multiple	Unknown/Multiple	None/Unknown		perf/should_run/T4830			
