我有
sample :: MVar a -> IO [a]
sample v = do
a <- takeMVar v
pure (a:unsafePerformIO (sample v))
这似乎是unsafePerformIO
合法使用给我的。但我很想知道如何避免它!是否有这种用途的模式?
答案 0 :(得分:7)
您可以使用线程Chan
和getChanContents
实现类似的功能:
sample :: MVar a -> IO [a]
sample v = do
c <- newChan
forkIO $ forever $ takeMVar v >>= writeChan c
getChanContents c
线程/ getChanContents
方法略胜一筹,因为至少你可以依赖MVar
持续进行。相反,unsafePerformIO
方法将在不可预测的点上运行takeMVar
,使putMVar
以类似的不可预测的方式阻塞。当然,getChanContents
方法将缓冲所有数据,可能需要更多内存。
然而,在我看来,这两种方法基本上都与懒惰IO类似,最好避免使用。