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予測不可能なポイントで実行さputMVarれ、同様に予測不可能な方法で s がブロックされます。もちろん、このgetChanContentsアプローチではすべてのデータがバッファリングされるため、より多くのメモリが必要になる可能性があります。

ただし、私の意見では、両方のアプローチは本質的に遅延 IO に似ており、これは避けるのが最善です。

于 2016-03-01T23:02:39.813 に答える