It might make sense if you have to do something like
> Just x <- timeout 1000 $ evalRandIO f > :tx x :: Bool > x Interrupted.
The calculation itself is completed, namely, reaches WHNF, so timeout does not catch it. The timeout 1000 function itself ends and returns Just undefined . An example where you can get a timeout to catch a lower bound would be
> import Control.DeepSeq > :set +m -- Multiline mode > let f :: Bool | f = f | > timeout 1000000 $ deepseq f (return f) Nothing
You will see that it freezes for a second, and then returns Nothing when deepseq does not finish evaluating f , so it can execute return f .
So your problem is that f = f gets a WHNF score instead of NF. To force NF, you need to use something like deepseq . Another, perhaps simpler example would be to simply use the $! operator $! , eg:
> let f :: Rand StdGen Bool | f = f | > timeout 1000000 $ evalRandIO $! f Nothing
source share