Why can't Haskell optimize this? (Nothing reproduces uselessly in the Maybe monad.)

Start with

boom :: Int -> Maybe a -> Maybe a
boom 0 x = x
boom n x = boom (n-1) (x >>= (\y -> Just y))

This is a simple function that repeatedly forces ( >>=) a Maybevalue into a trivial function \y -> Just y.

Now program

main = do
    let z = boom 10 (Nothing :: Maybe Int)
    putStrLn $ show z

runs very fast in a second. However the program

main = do
    let z = boom 10000000 (Nothing :: Maybe Int)
    putStrLn $ show z

it takes a few seconds, even if I compile ghc -O(GHC 7.8.3).

This means that Haskell cannot optimize this. Nothingrepeatedly translated into a function, even if there is no need for this.

My question is why ? Why can't he deduce that a Nothingalways ends as Nothingwith a repeated push? In other words, why can't he short-circuit immediately on the firstNothing ?

+4
3

, , . , ( , ). . , :

boom :: Int -> Maybe a -> Maybe a
boom 0 x = x
boom n x = x >>= (\y -> boom (n-1) (Just y))

n , x Just something. , , , thunk . , x Nothing, .

, "" GHC . , , , . , , , .

+7

-fforce-recomp

ghc 1.44s

ghc -O 1,44

ghc -O -fforce-recomp 0.00 0.04s

- boom maxBound (Nothing :: Maybe Int)

.

+1

boom n-1.

boom 100 x= boom (100-1) ...= boom (100-1-1) ... ..

( , - ).

0

All Articles