Ticket #4830 (closed bug: fixed)
Simplifier does case-to-let too eagerly
Description
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.
Change History
Note: See
TracTickets for help on using
tickets.
