
I tried -O2 -fno-cse. No difference.
I also tried -O2 -fno-full-laziness. BIG DIFFERENCE.
See also the very old GHC ticket at http://hackage.haskell.org/trac/ghc/ticket/917
I don't know if that's the problem or not, but it might plausibly be. Here's the smallest version of the program that I could come up with [which still misbehaves]: module Main (main) where import System.IO import System.Random main = do file_batch "01-Uniform" random_byte_uniform random_byte_uniform :: IO Int random_byte_uniform = randomRIO (0x00, 0xFF) random_file :: String -> Int -> IO Int -> IO () random_file f n rnd = do putStrLn $ "Save: " ++ f ++ " [" ++ show n ++ " bytes]" h <- openFile f WriteMode hSetBinaryMode h True mapM_ (\ _ -> rnd >>= hPutChar h . toEnum) [1..n] hClose h file_batch :: String -> IO Int -> IO () file_batch f rnd = mapM_ (\ k -> mapM_ (\ n -> random_file (f ++ "-" ++ show k ++ "x-" ++ [n]) (10 * 1024 * 1024 * k) rnd ) "ABCD" ) [1..4] If main calls random_file directly, the program seems to work OK, so the problem seems to be file_batch. Maybe. I don't really know. I had a go at playing with -ddump-simpl, but that just generated a 8 KB file which is utterly incomprehensible. (Well, the -O0 variant is just about comprehensible. The -O2 variant isn't. But it appears that *everything* gets inlined into main...) If anybody can figure out what's happening here, I'd be interested to know.