module T7865 where -- Our very expensive operation that we don't want to perform more than once -- Don't inline it so we can see exactly where it's called in the core {-# NOINLINE expensive #-} expensive :: Int -> Int expensive x = x * 100000 -- SpecConstr this function: recursive :: [Int] -> (Int,Int) -> (Int,Int) recursive list acc = case list of [] -> acc (x:xs) -> -- Our expensive tuple: -- The case is here mainly so that the expensive let isn't floated out before SpecConstr. let a' = case xs of [] -> acc (_:_) -> (let b = expensive x in (b * 2), x) -- Use the expensive value once and recurse. -- We recurse with (_:_:_) so that a specialisation is made for that pattern, -- which simplifies the case xs above. This exposes the expensive let. (p,q) = case a' of (p',q') -> recursive (x:x:xs) (q',p') -- Use the expensive value again. -- Our problem is that this shows up as a separate let-binding for expensive, instead of reusing -- the already computed value from above. in (p + fst a', q + snd a')