2012-09-03 16 views
14

Potremmo fondiamo due attraversamenti sopra la lista xs nell'espressioneCome posso unire due mappe sullo stesso elenco?

(map f xs, map g xs) 

in questo modo

unzip (map (\x -> (f x, g x)) xs) 

C'è reasearch sull'esecuzione di questa sorta di fusione automaticamente?

(C'è il rischio di creare una perdita di spazio qui se una delle liste restituiti si consuma prima che l'altro sono più interessato a prevenire l'attraversamento supplementare sopra xs di risparmio di spazio..)

Edit: In realtà non sto cercando di applicare la fusione alle attuali liste Haskell in memoria, dove questa trasformazione potrebbe non avere senso a seconda se lo unzip può essere fuso con i suoi consumatori. Ho un'impostazione in cui so che il unzip può fondersi (vedi "FlumeJava: pipeline parallele dati semplici ed efficienti").

+2

Non automatico, ma abbastanza bello in ogni caso: http://squing.blogspot.com/2008/11/beautiful-folding.html –

+1

A meno che il risultato di questo non si fonda con qualcos'altro, l'overhead di creare le coppie e decomprimerle essere più grande del costo dell'ulteriore attraversamento. – augustss

+1

@augusts Non se l'attraversamento è su un enorme file! Non ho intenzione di applicare questo alle liste attuali. – tibbe

risposta

4

Inoltre non completamente automatico, ma è possibile fornire a GHC un elenco di regole di riscrittura del genere. Vedi 7.14 Rewrite rules e Using rules. Quindi il compilatore utilizza queste regole per ottimizzare il programma durante la compilazione. (Si noti che il compilatore in nessun controllo modo se le regole ha alcun senso.)

Edit: per fare un esempio per questo particolare problema, possiamo scrivere:

{-# OPTIONS_GHC -fenable-rewrite-rules -ddump-rule-firings -ddump-rule-rewrites #-} 

import Data.Char 

{-# RULES 
"map/zip" forall f g xs. (,) (map f xs) (map g xs) = unzip (map (\x -> (f x, g x)) xs) 
    #-} 

main :: IO() 
main = let x = "abCD" in 
     print $ (,) (map toUpper x) (map toLower x) 

(livello superiore il nome della funzione nella regola è (,) :: a -> b -> (a, b)). Durante la compilazione, vedrai come vengono applicate le regole. L'opzione dump-rule-firings mostra un messaggio quando viene applicata una regola e -ddump-rule-rewrites visualizza ogni applicazione di regola in dettaglio - vedere 7.14.6. Controlling what's going on in rewrite rules.

+0

Non penso che possiamo scrivere una regola per abbinare questo tipo di espressioni. Le regole GHC devono iniziare con un nome di funzione. – tibbe

3

sono riuscito a trovare due risorse che cita la fusione (ONU) Codice postale come funzioni, almeno brevemente:

Josef Svenningsson. "Collegamento Fusion per accumulare Parametri Funzioni & Zip-come" http://www.cse.chalmers.se/~josefs/publications/fusion.pdf

Duncan Coutts. "Stream Fusion: fusione pratica di scorciatoia per tipi di sequenza coinduttiva" https://community.haskell.org/~duncan/thesis.pdf

Nessuna delle due fonti menziona esplicitamente questo tipo di "fusione tra fratelli".

+1

Non ho visto questa presentazione, ma qui ci sono scivoli di Josef circa [TupleFusion] (http://wiki.portal.chalmers.se/cse/uploads/FP/Josef_TupleFusion.pdf). – danr

+0

[Verso una strategia di tupling automatizzato] (http://dl.acm.org/citation.cfm?id=154643) potrebbe essere interessante. –

Problemi correlati