Pourquoi la fonction «ne rien faire» d’Haskell, id, consum-t-elle des tonnes de mémoire?

Haskell a une fonction d’identité qui renvoie l’entrée sans modification. La définition est simple:

id :: a -> a id x = x 

Donc, pour le plaisir, cela devrait sortir 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, l’interprète dit ghci: out of memory .

Comme id est une fonction assez simple, je ne m’attendrais pas à ce que ce soit une charge de mémoire à l’exécution ou à la compilation. A quoi sert toute la mémoire?

Nous connaissons le type d’ id ,

 id :: a -> a 

Et quand on le spécialise pour id id , la copie de gauche de l’ id a le type:

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

Et puis, quand vous le spécialisez à nouveau pour l’ id le plus à gauche dans id id id , vous obtenez:

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

Donc, vous voyez chaque id vous ajoutez, la signature de type de l’ id le plus à gauche 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.