views:

200

answers:

1

Will GHC perform tail-call optimization on the following function by default? The only weird thing about it is that it is recursively defining an IO action, but I don't see why this couldn't be TCO'd.

import Control.Concurrent.MVar

consume :: MVar a -> [a] -> IO ()
consume _ [] = return ()
consume store (x:xs) = do putMVar store x
                          consume store xs
+19  A: 

Since your code is equivalent to

consume store (x:xs) = putMVar store >> consume store xs

the call does not actually occur in tail position. But if you run ghc -O and turn on the optimizer, the -ddump-simpl option will show you the output of GHC's intermediate code, and it does indeed optimize into a tail-recursive function, which will compile into a loop.

So the answer is GHC won't optimize this by default; you need the -O option.

(Experiments done with GHC version 6.10.1.)

Norman Ramsey
+1 for a great, clear answer.
Tony k
Thanks for the help, I did not know about -ddump-simpl. That is really useful!
Geoff