{-# LANGUAGE CPP #-}

#define F_BODY     if a then (x + x + x + x + x + x) else (x + if b then x else 0)

#define F_USE(f)   if b then (if a then f 3 else f 5) else f 0

module FVDiscountSim (outer_BAD, outer_GOOD) where

-- This example is abstracted from nofib boyer2, onewayunify1.

-- With a local definition, having a free variable, local_f is not inlined
-- But it should be, because at the call site in F_USE, 'b' is known
-- to be True or False respectively
outer_BAD a b =
  let local_f :: Integer -> Integer
      local_f x = F_BODY
  in F_USE( local_f )


-- With a top-level defintion, floated_f is inlined
-- because we get a discount for 'b'.
floated_f :: Bool -> Bool -> Integer -> Integer
floated_f a b x = F_BODY

outer_GOOD a b = F_USE(floated_f a b)
