import Control.Monad import Control.Concurrent.MVar import Control.Concurrent import Text.Printf import System.Random fuzz :: IO () fuzz = do seconds <- getStdRandom random :: IO Double threadDelay $ round (realToFrac (1000000 * seconds)) counterManager :: MVar Integer -> Chan Integer -> Chan [String] -> IO () counterManager counter counterCh printerCh = forever $ do fuzz incrementBy <- readChan counterCh fuzz newCount <- modifyMVar counter (\i -> return (i + 1, i + 1)) fuzz writeChan printerCh [printf "The count is %d" newCount, "---------------"] fuzz printerManager :: Chan [String] -> IO () printerManager ch = forever $ do fuzz rows <- readChan ch fuzz mapM_ putStrLn rows fuzz main :: IO () main = do counter <- newMVar 0 counterCh <- newChan printerCh <- newChan forkIO $ counterManager counter counterCh printerCh forkIO $ printerManager printerCh writeChan printerCh ["Starting up"] replicateM_ 10 (writeChan counterCh 1) -- join counterCh writeChan printerCh ["Finishing up"] -- join printerCh threadDelay $ 20 * 1000000