OK, what did I do wrong here? module Main () where import Data.List top = 10 ^ 8 :: Int main = do let numbers = [1 .. top] print $ foldl' (+) 0 numbers -- Runtime is 20 seconds. #include <stdio.h> int main(void) { int total = 0; int n; for (n = 1, n < 100000000; n++) total += n; printf("%d", n); } // Runtime is 0.8 seconds. module Main () where import Data.List top = 10 ^ 8 :: Int kernel i o = if i < top then o `seq` kernel (i+1) (o+i) else o main = do print $ kernel 1 0 -- Runtime is 0.5 seconds. Clearly these two nearly identical Haskell programs should have exactly the same runtime. Instead, one is 40x slower. Clearly something has gone catastrophically wrong here. The whole point of GHC's extensive optimiser passes are to turn the first example into the second example - but something somewhere hasn't worked. Any suggestions?