In termini semplici, un valore di tipo Int
può essere un'espressione non valutata. Il valore effettivo non viene calcolato finché non si "guarda" il valore.
Un valore di tipo Int#
è un risultato valutato. Sempre.
Come risultato, una struttura di dati Int
che vive nell'heap. Un Int#
è ... solo un numero intero a 32 bit. Può vivere in un registro della CPU. Puoi operare su di esso con una singola istruzione macchina. Non ha quasi nessun sovraccarico.
Al contrario, quando si scrive, per esempio, x + 1
, non sei in realtà calcolo x + 1, si sta creando una struttura di dati nel mucchio che dice "quando si vuole calcolare questo, fare x + 1" .
In parole semplici, Int#
è più veloce, perché non può essere pigro.
Quando si deve usare? Quasi mai. Questo è il lavoro del compilatore. L'idea è che scrivi un bel codice Haskell di alto livello che coinvolge Int
e il compilatore calcola dove può sostituire Int
con Int#
. (Speriamo!) Se così non fosse, è quasi sempre più facile inserire alcune annotazioni di rigore piuttosto che giocare direttamente con Int#
. (È anche non portatile, solo GHC usa Int#
- anche se attualmente non ci sono altri compilatori Haskell ampiamente usati.)
Ho scritto [un articolo] (http://alpmestan.com/posts/2013 -10-02-oh-my-laziness.html) su questo, potresti voler dare un colpo. –