7

Me gustaría saber cómo podemos implementar productor/consumidor en un lenguaje de programación funcional como Haskell? y cómo será diferente de un lenguaje Imperativo? Mi comprensión del lenguaje de programación funcional es primitivo. Cualquier ayuda será apreciada.¿Problema de productor y consumidor en Haskell?

+0

Esto está muy cerca de http://stackoverflow.com/questions/1234947/can-producer-consumer-problem-be-solved-without-using-assignment. ¿Revisaste las soluciones presentadas allí? – nlucaroni

Respuesta

14

A/abstracción consumidor productor utilizando hilos de preferencia y los mensajes pasados ​​a través de un canal:

import Data.Char 
import Control.Concurrent 
import Control.Concurrent.Chan 

main = do 
    c <- newChan 
    cs <- getChanContents c  -- a lazy stream of events from eventReader 
    forkIO (producer c)   -- char producer 
    consumer cs 

    where 
    -- thread one: the event producer 
    producer c = forever $ do 
     key <- getChar 
     writeChan c key 

    -- thread two: the lazy consumer 
    consumer = mapM_ print . map shift 
     where shift c | isAlpha c = chr (ord c + 1) 
          | otherwise = c 

que usaría un modelo similar en Erlang. Hilos para representar al consumidor y productor, y un conjunto de mensajes compartidos entre ellos, cada uno actuando de forma asincrónica.

+2

Esta respuesta describe cómo uno podría resolver este problema imperativamente. O más precisamente, cómo generar funcionalmente un cálculo imperativo que resuelva el problema. Me pregunto si Shiva estaba buscando una solución puramente funcional. – Conal

6

Agregaré a la respuesta excelente de dons que el mecanismo subyacente aquí es algo llamado MVar, y es un contenedor imperativo, paralelo para un valor. Usted "pone" y "entra" dentro y fuera de un MVar. Obtener un bloque MVar vacío, al igual que poner uno completo. Es a la vez un mecanismo de comunicación y un mecanismo de sincronización. Creo que fue inventado por Arvind como parte del proyecto Monsoon/* t. Hay una hermosa book by Nikhil and Arvind que explica su dialecto de pH del paralelo Haskell. Muchas de las ideas se han adoptado en GHC, y vale la pena leer el libro.

2

Además de los enfoques de estado mencionados por Norman y Don, también se puede pensar en la aplicación de la función normal y la pereza como productor y consumidor.

Aquí es un productor de los números naturales:

nats = [1..] 

Y aquí es un consumidor que calcula los cuadrados de los números:

squares = map (\x -> x * x) nats 

productores como yield return en C# o generadores en Python a menudo se puede expresar así: como simples listas perezosas en Haskell.

+0

Sin embargo, en Python los generadores pueden tener efectos secundarios (a diferencia de las listas puras). también puede lograr eso con listas monádicas, y también puede generar aquellas con "rendimiento" como en Python con el transformador de mónada GeneratorT del paquete de generador. – yairchu

Cuestiones relacionadas