Документы System.IO содержат загадочную недокументированную функцию fixIO
. Свой источник только добавляет тайну:
fixIO :: (a -> IO a) -> IO a
fixIO k = do
m <- newEmptyMVar
ans <- unsafeInterleaveIO (takeMVar m)
result <- k ans
putMVar m result
return result
Это похоже на моральный эквивалент разыменования NULL (чтение с пустого MVar). Действительно, попробуйте:
import System.IO
main = fixIO $ \x -> putStrLn x >> return x
приводит к ошибке "поток, заблокированный бесконечно в операции MVar"
В поиске ничего не появляется, чтобы сохранить 15-летнее сообщение от самого Саймона Пейтона-Джонса, в котором он предоставляет вышеупомянутый источник, и надеется, что это придаст смысл ясно (и все же здесь я).
Может кто-то пролить свет на это? Что делает fixIO и когда я должен его использовать?