# Capture some state in Haskell

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.

• Sounds like a textbook example of message passing: a bunch of threads writing console messages to a TQueue, and one thread reading from it in a loop and printing each message – Benjamin Hodgson May 28 '16 at 12:33

## 1 Answer

What you have will work just fine:

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

getPutStrLn' :: IO (String -> IO ())
getPutStrLn' = do
sync <- newMVar ()
return (\s -> do _ <- takeMVar sync
putStrLn s
putMVar sync ())

type Logger = String -> IO ()

second = 1000000

child1 :: 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.