I want to capture some state in a Haskell function. For instance, I have many thread trying to print on the console and I want the to play nice with each other. So I want to have some XX to make the police among the threads and I want that to be hidden as most as possible to my client.I can think of a few alternatives, but I am not sure what is the most idiomatic in Haskell:Write a logger running on his independent thread, as in the parallel and concurrent Haskell book.Write a function like so:getPutStrLn' :: IO (String -> IO ())getPutStrLn' = do   sync <- newMVar ()   return (\s -> do _ <- takeMVar sync                    putStrLn s                    putMVar sync ())Separate concerns and put the said state somewhere else, calling getPutStrLn as part of a pipeline of effectual streams but not from within the threads.
Capture some state in Haskell
multithreading;haskell;concurrency;state
What you have will work just fine:import Control.Concurrentimport Control.Concurrent.MVarimport Control.MonadgetPutStrLn' :: IO (String -> IO ())getPutStrLn' = do   sync <- newMVar ()   return (\s -> do _ <- takeMVar sync                    putStrLn s                    putMVar sync ())type Logger = String -> IO ()second = 1000000child1 :: Logger -> IO ()child1 log = do  forever $ do log I am child 1               threadDelay (1*second)child2 log = do  forever $ do log I am child 2               threadDelay (2*second)main = do  log <- getPutStrLn'  forkIO $ child1 log  forkIO $ child2 log  threadDelay (10*second)You are encapsulating the state in the log computation - that's the perfect place for it.