I have
sample :: MVar a -> IO [a]
sample v = do
a <- takeMVar v
pure (a:unsafePerformIO (sample v))
which appears to be a legitimate use of unsafePerformIO to me. But I am very interested to know how to avoid it! Is there a pattern for this use already?
You can implement a similar function using a thread, a
ChanandgetChanContents:The thread/
getChanContentsapproach is slightly better, since at least you can rely on theMVarbeing continuously taken. Instead, theunsafePerformIOapproach will runtakeMVarat impredictable points, making theputMVars blocking in a similarly impredictable way. Of course, thegetChanContentsapproach 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.