采样一个MVar,我可以避免不安全的PerformIO吗?

时间:2016-03-01 22:41:13

标签: haskell unsafe-perform-io

我有

sample :: MVar a -> IO [a]
sample v = do
   a <- takeMVar v
   pure (a:unsafePerformIO (sample v))

这似乎是unsafePerformIO合法使用给我的。但我很想知道如何避免它!是否有这种用途的模式?

1 个答案:

答案 0 :(得分:7)

您可以使用线程ChangetChanContents实现类似的功能:

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类似,最好避免使用。