0

我有

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

unsafePerformIO这对我来说似乎是合法的使用。但我很想知道如何避免它!已经有这种用途的模式了吗?

4

1 回答 1

7

您可以使用线程 aChan和实现类似的功能getChanContents

sample :: MVar a -> IO [a]
sample v = do
   c <- newChan
   forkIO $ forever $ takeMVar v >>= writeChan c
   getChanContents c   

线程/getChanContents方法稍微好一些,因为至少你可以依赖于MVar被持续采用。相反,该unsafePerformIO方法将takeMVar在不可预测的点上运行,使putMVars 以同样不可预测的方式阻塞。当然,该getChanContents方法将缓冲所有数据,可能需要更多内存。

但是,这两种方法本质上都类似于惰性 IO,我认为最好避免这种方法。

于 2016-03-01T23:02:39.813 回答