Haskell a une fonction d'identité qui renvoie l'entrée inchangée. La définition est simple:
id :: a -> a
id x = x
Donc, pour le plaisir, cela devrait afficher 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
Après quelques secondes (et environ 2 Go de mémoire selon le Gestionnaire des tâches), la compilation échoue avec ghc: out of memory
. De même, dit l'interprète ghci: out of memory
.
Comme id
c'est une fonction assez simple, je ne m'attendrais pas à ce que ce soit une charge de mémoire au moment de l'exécution ou de la compilation. À quoi sert toute la mémoire?
id
s. En VIM, avec le curseur sur la définitionf
, faites ceci::s/id id/id . id ./g
.Réponses:
Nous connaissons le type de
id
,Et quand nous nous spécialisons ceci pour
id id
, la copie de gauche deid
a le type:Et puis, lorsque vous spécialisez à nouveau cela pour le plus
id
à gaucheid id id
, vous obtenez:Donc, vous voyez chaque que
id
vous ajoutez, la signature de type la plus à gaucheid
est deux fois plus grande.Notez que les types sont supprimés lors de la compilation, donc cela ne prendra que de la mémoire dans GHC. Cela ne prendra pas de mémoire dans votre programme.
la source
id
est répétén
fois, l'espace de son type est proportionnel à2^n
. Le type inféré dans le code de Ryan aurait besoin de2^27
références à sa variable de type en plus de l'autre structure nécessaire pour représenter le type, qui est probablement beaucoup plus grande que ce que vous attendez de la plupart des types.