content: {-# OPTIONS_GHC -O2 -fforce-recomp #-}
  {-# LANGUAGE BangPatterns #-}
  
  -- | This ticket is about the demand `seq` puts its first argument under and how
  -- that affects call demands.
  module T18957 where
  
  -- | Should put its first argument under head demand
  -- Note that seq' is like seq, but NOINLINE, so the calling code will not have
  -- access to the case binder. That is the difference between 'h1' and 'h2'.
  seq' :: a -> b -> b
  seq' a b = seq a b
  {-# NOINLINE seq' #-}
  
  -- | The first argument is evaluated at once, but called every time it's
  -- evaluated
  g :: (Int -> Int) -> Int -> Int
  g f x = if x < 100 then f x else 200
  
  -- | The first argument is evaluated multiple times, but called at most once
  -- every time it's evaluated
  h1 :: (Int -> Int) -> Int -> Int
  h1 f x = f `seq'` if x < 100 then f x else 200
  
  -- | Like h1, but using `seq` directly, which will rewrite the call site
  -- of @f@ to use the case binder instead, which means we won't evaluate it an
  -- additional time. So evaluated once and called once.
  h2 :: (Int -> Int) -> Int -> Int
  h2 f x = f `seq` if x < 100 then f x else 200
  
  -- | The first argument is evaluated lazily and multiple times, but called every
  -- time it's evaluated.
  h3 :: (Int -> Int) -> Int -> Int
  h3 f x = if x < 100 then f x + f (x+1) else 200
  