Cos’è la Fusion Stream di Haskell

Cos’è la Fusion Stream di Haskell e come la uso?

Il documento a cui Logan punta è grandioso, ma è un po ‘difficile. (Basta chiedere ai miei studenti.) È anche una grande quantità di “come funziona la fusione del stream” e solo una frazione di “quale stream di fusione è e come si può usarlo”.

Il problema che la fusione del stream risolve è che i codici funzionali scritti spesso assegnano liste intermedie, ad esempio, per creare una lista infinita di numeri di nodes, potresti scrivere

 nodenames = map ("n"++) $ map show [1..] 

Il codice ingenuo alloca una lista infinita di numeri interi [1, 2, 3, ...] , una lista infinita di stringhe ["1", "2", "3", ...] , e infine una lista infinita di nomi ["n1", "n2", "n3", ...] . Questa è un’eccessiva allocazione.

Ciò che fa stream fusion è tradurre una definizione come nodenames in qualcosa che usa una funzione ricorsiva che assegna solo ciò che è necessario per il risultato. In generale, l’eliminazione dell’allocazione degli elenchi intermedi è chiamata deforestazione .

Per utilizzare la fusione di flussi, è necessario scrivere funzioni di lista non ricorsive che utilizzano le funzioni della libreria stream-fusion descritta nel biglietto GHC 915 ( map , foldr e così via) anziché ricorsività esplicita. Questa libreria contiene nuove versioni di tutte le funzioni Prelude che sono state riscritte per sfruttare la fusione stream. Apparentemente questa roba è prevista per la prossima versione di GHC (6.12), ma non è nella versione stabile attuale (6.10). Se vuoi usare la biblioteca, Porges ha una semplice spiegazione nella sua risposta.

Se in realtà vuoi una spiegazione di come funziona lo stream fusion, posta un’altra domanda — ma è molto più difficile.

Per quanto ne so, e contrariamente a quanto affermato da Norman, la fusione del stream non è attualmente implementata nella base di GHC (cioè non si possono usare solo le funzioni di Preludio). Per ulteriori informazioni, consultare il biglietto GHC 915 .

Per utilizzare la fusione di flussi è necessario installare la libreria stream-fusion, importare Data.List.Stream (è anche ansible importare Control.Monad.Stream) e utilizzare solo le funzioni da quel modulo anziché le funzioni Prelude. Ciò significa importare il Preludio nascondendo tutte le funzioni della lista di default e non usando i costrutti [x..y] o la comprensione delle liste.

Non è corretto, che quando GHC in 6.12 usa quelle nuove funzioni per impostazione predefinita, implementerà anche [x..y] e comprenderanno le comprensioni in quel modo non ricorsivo? Perché l’unica ragione per cui non sono la riga giusta, è che sono interni e non scritti in realtà in Haskell, ma più simili a parole chiave, per motivi di velocità e / o perché non si sarebbe in grado di ridefinire quella syntax.