I am going to demonstrate the problem using the following example program

```
{-# LANGUAGE BangPatterns #-}

data Point = Point !Double !Double

fmod :: Double -> Double -> Double
fmod a b | a < 0     = b - fmod (abs a) b 
         | otherwise = if a < b then a 
                       else let q = a / b 
                            in b * (q - fromIntegral (floor q :: Int))

standardMap :: Double -> Point -> Point
standardMap k (Point q p) = 
   Point (fmod (q + p) (2 * pi)) (fmod (p + k * sin(q)) (2 * pi))

iterate' gen !p = p : (iterate' gen $ gen p)

main = putStrLn 
     . show 
     . (\(Point a b) -> a + b) 
     . head . drop 100000000 
     . iterate' (standardMap k) $ (Point 0.15 0.25)
    where k = (cos (pi/3)) - (sin (pi/3))

```

Here `standardMap k` is the parametrized function and `k=(cos (pi/3))-(sin (pi/3))` is a parameter. If i compile this program with `ghc -O3 -fllvm` the execution time on my machine is approximately `42s`, however, if I write `k` in the form `0.5 - (sin (pi/3))` the execution time equals `21s` and if I write `k = 0.5 - 0.5 * (sqrt 3)` it will take only `12s`. 

The conclusion is that `k` is reevaluated on each call of `standardMap k`.

Why this is not optimized?

P.S. compiler ghc 7.6.3 on archlinux

**EDIT**

For those who are concerned with the weird properties of `standardMap` here is a simpler and more intuitive example, which exhibits the same problem

```
{-# LANGUAGE BangPatterns #-}

data Point = Point !Double !Double

rotate :: Double -> Point -> Point
rotate k (Point q p) = 
   Point ((cos k) * q - (sin k) * p) ((sin k) * q + (cos k) * p)

iterate' gen !p = p : (iterate' gen $ gen p)

main = putStrLn 
     . show 
     . (\(Point a b) -> a + b) 
     . head . drop 100000000 
     . iterate' (rotate k) $ (Point 0.15 0.25)
   where --k = (cos (pi/3)) - (sin (pi/3))
         k = 0.5 - 0.5 * (sqrt 3)

```

**EDIT** 

Before I asked the question I have tried to make `k` strict, the same way Don suggested, but with `ghc -O3` I didn't see a difference. The solution with strictness works if the program is compiled with `ghc -O2`. I missed that because I didn't try all possible combinations of flags with the all possible versions of the program.

So what is the difference between `-O3` and `-O2` that affects such cases?

Should I prefer `-O2` in general?

**EDIT** 

As observed by Mike Hartl and others, if `rotate k` is changed into `rotate $ k` or `standardMap k` into `standardMap $ k`, the performance is improved, though it is not the best possible (Don's solution). Why?