The System.IO docs contains a mysterious, undocumented function fixIO
. Its source only adds to the mystery:
fixIO :: (a -> IO a) -> IO a
fixIO k = do
m <- newEmptyMVar
ans <- unsafeInterleaveIO (takeMVar m)
result <- k ans
putMVar m result
return result
This appears to do the moral equivalent of dereferencing NULL (reading from an empty MVar). Indeed, trying it:
import System.IO
main = fixIO $ \x -> putStrLn x >> return x
results in an error "thread blocked indefinitely in an MVar operation"
Searching turns up nothing save a 15 year old message from Simon Peyton-Jones himself, in which he provides the above source, and hopes that it would make the meaning clear (and yet here I am).
Can someone please shed some light on this? What does fixIO do and when should I use it?