scrivo un programma che conta le frequenze di NGrams in un corpus. Ho già una funzione che consuma un flusso di gettoni e produce NGrams di un unico ordine:Conduit: più consumatori Ruscello
ngram :: Monad m => Int -> Conduit t m [t]
trigrams = ngram 3
countFreq :: (Ord t, Monad m) => Consumer [t] m (Map [t] Int)
Al momento posso solo collegare un flusso dei consumatori ad una fonte di flusso:
tokens --- trigrams --- countFreq
Come fare Collego più utenti dello stream alla stessa sorgente di streaming? Mi piacerebbe avere qualcosa di simile:
.--- unigrams --- countFreq
|--- bigrams --- countFreq
tokens ----|--- trigrams --- countFreq
'--- ... --- countFreq
Un plus sarebbe quella di eseguire ogni consumatore in parallelo
EDIT: Grazie a Petr mi si avvicinò con questa soluzione
spawnMultiple orders = do
chan <- atomically newBroadcastTMChan
results <- forM orders $ \_ -> newEmptyMVar
threads <- forM (zip results orders) $
forkIO . uncurry (sink chan)
forkIO . runResourceT $ sourceFile "test.txt"
$$ javascriptTokenizer
=$ sinkTMChan chan
forM results readMVar
where
sink chan result n = do
chan' <- atomically $ dupTMChan chan
freqs <- runResourceT $ sourceTMChan chan'
$$ ngram n
=$ frequencies
putMVar result freqs
Si desidera che quando "token" restituisce un valore, tutti i "... grammi" lo ricevono? –