Marcin 'Qrczak' Kowalczyk wrote:
Fri, 16 Feb 2001 04:14:26 -0800, Simon Peyton-Jones <simonpj@microsoft.com> pisze:
fixIO m = do { v <- newEmptyMVar ; result <- m (unsafePerformIO (takeMVar v)) ; putMVar v result ; return result }
If we have unsafePerformIO, why not this?
fixIO m = let x = unsafePerformIO (m x) in return $! x
Why the strict application? You probably want: do { fixIO (\x -> return (x+1)); return 2 } to evaluate to (return 2). But the version with strict application diverges. By the way, we can prove that it should evaluate to (return 2) using the monadic-fixpoint axiomatization: do { fixIO (\x -> return (x+1)); return 2 } = {expand do} fixIO (\x -> return (x+1)) >>= \_ -> return 2 = {rewrite} fixIO (return . (+1)) >>= \_ -> return 2 = {mfix (return . h) = return (fix h), mfix = fixIO for the IO monad} return (fix (+1)) >>= \_ -> return 2 = {return x >>= f = f x} return 2 So, it looks like: fixIO m = let x = unsafePerformIO (m x) in return x will do a better job. -Levent.