# FixIO/ Tackling Awkward Squad

**Levent Erkok
**
erkok@cse.ogi.edu

*Fri, 16 Feb 2001 09:51:03 -0800*

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.