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 putMVars 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.
sampleworked really safely, then it would probably be in the library already. – leftaroundabout Mar 1 '16 at 23:06unsaferoute, you should at least useunsafeInterleaveIOhere, which is the intended method of implementing lazy IO. Note thatgetChanContentsitself usesunsafeInterleaveIOin order to lazily produce the entire contents of the Chan. – user2407038 Mar 2 '16 at 3:35