11

que tienen una función monádica getRate:¿Cómo puedo usar parMap con una función monádica?

getRate :: String -> IO Double 

Me gustaría asignar esta función a través de una lista de cadena de. Normalmente, sólo haría:

mapM getRate ["foo", "bar"] 

pero ya que cada llamada a getRate hace llamadas de red, me gustaría poner en paralelo el mapa de modo que cada tasa se capta en un hilo separado (o al menos disperso entre las colas) Estoy pensando en algo así como

parMapM getRate ["foo", "bar"] 

pero no hay ninguna función parMapM y parMap no funciona con funciones monádicos.

¿Qué puedo hacer?

Respuesta

6

Debe usar Control.Concurrente y sincronizar alrededor de un Control.Concurrent.MVar; algo así como:

fork1 :: (a -> IO b) -> a -> IO (MVar b) 
fork1 f x = 
    do 
    cell <- newEmptyMVar 
    forkIO (do { result <- f x; putMVar cell result }) 
    return cell 

fork :: (a -> IO b) -> [a] -> IO [MVar b] 
fork f = mapM (fork1 f) 

join :: [MVar b] -> IO [b] 
join = mapM takeMVar 

forkJoin :: (a -> IO b) -> [a] -> IO [b] 
forkJoin f xs = (fork f xs) >>= join 

partes del presente (tenedor, se inscribe) mirar secuencial. Lo que está sucediendo en la práctica es que los hilos se disparan secuencialmente en el tenedor y el encuentro avanza a la espera de cada hilo por turno. Pero el IO ocurre concurrentemente.

Tenga en cuenta que si necesita llamar a funciones extranjeras debe usar forkOS en lugar de forkIO.

+0

Esto es perfecto, ¡gracias! – Bill

Cuestiones relacionadas