How can I use parMap with a monadic function? How can I use parMap with a monadic function? multithreading multithreading

How can I use parMap with a monadic function?


You should use Control.Concurrent and synchronize around a Control.Concurrent.MVar; something like:

fork1 :: (a -> IO b) -> a -> IO (MVar b)fork1 f x =  do    cell <- newEmptyMVar    forkIO (do { result <- f x; putMVar cell result })    return cellfork :: (a -> IO b) -> [a] -> IO [MVar b]fork f = mapM (fork1 f)join :: [MVar b] -> IO [b]join = mapM takeMVarforkJoin :: (a -> IO b) -> [a] -> IO [b]forkJoin f xs = (fork f xs) >>= join

Parts of this (fork, join) look sequential. What's happening in practice is the threads are fired off sequentially in fork and rendezvous walks through waiting for each thread in turn. But the IO happens concurrently.

Note that if you need to call foreign functions you should use forkOS instead of forkIO.


There is also a monad-parallel package which provides mapM :: MonadParallel m => (a -> m b) -> [a] -> m [b]. Looking at the IO instance for MonadParallel it does it the same way as in Dominic's answer.