content: 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')
  
  