You can implement a similar function using a thread, a Chan
and getChanContents
:
sample :: MVar a -> IO [a]
sample v = do
c <- newChan
forkIO $ forever $ takeMVar v >>= writeChan c
getChanContents c
The thread/getChanContents
approach is slightly better, since at least you can rely on the MVar
being continuously taken. Instead, the unsafePerformIO
approach will run takeMVar
at impredictable points, making the putMVar
s blocking in a similarly impredictable way. Of course, the getChanContents
approach will buffer all the data, possibly requiring more memory.
However, both approaches are essentially similar to lazy IO, which is best to be avoided, in my opinion.
sample
worked really safely, then it would probably be in the library already. – leftaroundabout Mar 1 '16 at 23:06unsafe
route, you should at least useunsafeInterleaveIO
here, which is the intended method of implementing lazy IO. Note thatgetChanContents
itself usesunsafeInterleaveIO
in order to lazily produce the entire contents of the Chan. – user2407038 Mar 2 '16 at 3:35