[Haskell-cafe] Lazy IO

Reid Barton rwbarton at math.harvard.edu
Thu Jul 10 09:47:15 EDT 2008

On Wed, Jul 09, 2008 at 11:05:47PM -0400, Ronald Guida wrote:
> Question: If I can't change my function f (in this case, accumulator),
> then is it possible to get the effect I want without having to resort
> to "unsafeInterleaveIO"?

Here's a possibility; you may or may not like it.

module Main

import Control.Concurrent
import Control.Concurrent.Chan
import Control.Concurrent.MVar
import Control.Monad

{- promptInt, accumulator, makeAccPrompt as before -}

main :: IO ()
main = do
  inChan <- newChan
  outMVar <- newEmptyMVar
  forkIO $ (getChanContents inChan) >>= (mapM_ (putMVar outMVar) . accumulator)
  let go = do
        p <- takeMVar outMVar
        m <- promptInt (makeAccPrompt p)
        case m of
          Just n -> do
            writeChan inChan n
            ns <- go
            return $ n:ns
          Nothing -> return []
  xs <- go
  print xs

The unsafeInterleaveIO is now hidden inside getChanContents.  (I have
an outMVar rather than an outChan just in case accumulator could
produce lots of output before consuming much of its input.)

Reid Barton

More information about the Haskell-Cafe mailing list