2014-05-19 12 views
108

Haskell ha una funzione di identità che restituisce l'input invariato. La definizione è semplice:Perché la funzione "fa niente" di Haskell, id, consuma tonnellate di memoria?

id :: a -> a 
id x = x 

Così, per divertimento, questo dovrebbe uscita 8:

f = id id id id id id id id id id id id id id id id id id id id id id id id id id id 
main = print $ f 8 

Dopo pochi secondi (e circa 2 GB di memoria secondo Task Manager), la compilazione fallisce con ghc: out of memory. Allo stesso modo, l'interprete dice ghci: out of memory.

Poiché id è una funzione piuttosto semplice, non mi aspetto che sia un carico di memoria in fase di esecuzione o in fase di compilazione. A cosa serve tutta la memoria?

+10

Si desidera comporre quei 'id's. In VIM, con il cursore sulla definizione di 'f', fai questo:': s/id id/id. id./g'. –

+1

Ti ho dato il tuo primo distintivo d'oro, alzando la tua domanda da +99 a +100 :). L'ho trovato esaminando tutte le domande con 99 voti e coloro che le hanno pubblicate senza badge d'oro;). –

risposta

128

Sappiamo che il tipo di id,

id :: a -> a 

E quando specializzati questo per id id, il lasciato copia di id è digitare:

id :: (a -> a) -> (a -> a) 

E poi, quando vi specializzate di nuovo per il più a sinistra id in id id id, si ottiene:

id :: ((a -> a) -> (a -> a)) -> ((a -> a) -> (a -> a)) 

Così vedete ogni id aggiunto, la firma del tipo più a sinistra dello id è due volte più grande.

Nota che i tipi vengono cancellati durante la compilazione, quindi questo occuperà solo memoria in GHC. Non occuperà memoria nel tuo programma.

+9

Divertente ma rilevante: http://britton.disted.camosun.bc.ca/jbchessgrain.htm – Barmar

+0

Ricordo che Okasaki si imbatté in qualche problema simile quando scrisse un calcolatore RPN incorporato in Haskell. – dfeuer

+3

La domanda, forse, è se GHC dovrebbe trovare un modo per gestire questo genere di cose con più grazia. In particolare, il tipo è molto grande se scritto per intero, ma c'è un'enorme quantità di duplicazione: la condivisione potrebbe essere usata per comprimere queste cose? C'è un modo efficace per elaborarli? – dfeuer

Problemi correlati