2016-04-24 12 views
16

Supponiamo che io sonoapplicazione parziale di severe costruttori

data Foo a = Foo !Int a [a] | Bar [a] 

così il costruttore Foo è severo nel suo primo argomento, che verrà spacchettato. Supponiamo inoltre che sto passando Foo n a una funzione di ordine superiore f e che lo f non viene allineato (in questo modo viene passato effettivamente lo Foo n). Il Core che ottengo con -O2 indica che n viene inserito nella casella e quindi passato a Foo e il risultato viene passato a f. La mia domanda: dovrei essere meglio chiamare

f (\a b -> Foo n a b) 

per evitare la boxe n? O questo potrebbe portare ad altri problemi di prestazioni?


realtà stavo pensando di definire

foo' !n = \a b -> Foo n a b 

e chiamare f (foo' n), che ho pensato che dovrebbe fare la stessa cosa, ma credo che sia meglio chiedere specificamente.

+2

Per quanto ne so, Foo n' viene trasformato in '\ a b -> Foo n a b' dal compilatore, perché non ci sono costruttori parzialmente applicati nella macchina STG. – augustss

+0

@augusts, 'Foo' è tradotto in una * funzione * rigorosa che chiama il vero costruttore, per quanto posso dire. Si verifica ulteriormente l'unboxing tra la semplificazione e STG? – dfeuer

+0

Tutto quello che intendevo era che i costruttori parzialmente applicati sono tradotti in funzioni. Poi c'è un altro livello di traduzione per costruttori rigorosi. – augustss

risposta

3

Ho aperto GHC Trac ticket 12990 per questo. Reid Barton e Simon Peyton Jones hanno suggerito una correzione (consentendo di inserire la funzione wrapper parzialmente applicata), che ho inviato come GHC Phabricator differential D2891. La patch è stata applicata al ramo principale e sarà inclusa in GHC 8.2.