
Hi, I am having difficulty debugging a troublesome stack overflow, which I think might be related to calling unsafePerformIO from within the IO monad. So I have the following code: import System.Random import System.IO.Unsafe import Data.Time.Clock timedIterateIO :: Int -> (a -> a) -> a -> IO a timedIterateIO durationSecs f x = do t0 <- getCurrentTime timedIterateIO' t0 x where duration' = fromIntegral durationSecs timedIterateIO' t0 x = do let y = f x t <- getCurrentTime let d = diffUTCTime t t0 if d >= duration' then return y else timedIterateIO' t0 y f x = unsafePerformIO $ do m <- randomRIO (1,2) return (m+x) The idea of the timedIterateIO function is that it should repeatedly apply f to x until a specified duration is up. The use case is for game search, where I want to keep searching until time is up, and then play the best move I've found at that point. So the following works: *Main> timedIterateIO 1 (+1) 0 45580 (1.01 secs, 360357840 bytes) The following also seems to work: *Main> unsafePerformIO $ timedIterateIO 1 f 0 67866 (1.25 secs, 394938540 bytes) Now, in the real use case, I have another function, g let's say. It is similar to f, in that it uses unsafePerformIO internally to get random numbers. It's proven to work under normal circumstances, for example: *Main> (!! 100) $ iterate g x works, and completes in around a second. However, the following doesn't work, failing with a stack overflow: *Main> unsafePerformIO $ timedIterateIO 1 g x Any ideas? Thanks, David