web-dev-qa-db-fra.com

Pourquoi la fonction "ne rien faire" de Haskell, id, consomme-t-elle des tonnes de mémoire?

Haskell a une fonction d'identité qui retourne l'entrée inchangée. La définition est simple:

id :: a -> a
id x = x

Donc, pour le plaisir, cela devrait produire 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.

Puisque id 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?

112
Ryan

Nous connaissons le type de id,

id :: a -> a

Et quand nous le spécialisons pour id id, la copie gauche de id a le type:

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

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

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

Ainsi, vous voyez chaque id que vous ajoutez, la signature de type du 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. Il ne prendra pas de mémoire dans votre programme.

132
Dietrich Epp