Haskell tiene una función de identidad que devuelve la entrada sin cambios. La definición es simple:
id :: a -> a
id x = x
Entonces, para divertirse, esto debería generar 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
Después de unos segundos (y aproximadamente 2 gb de memoria según el Administrador de tareas), la compilación falla con ghc: out of memory
. Del mismo modo, dice el intérprete ghci: out of memory
.
Dado que id
es una función bastante simple, no esperaría que sea una carga de memoria en tiempo de ejecución o tiempo de compilación. ¿Para qué se utiliza toda la memoria?
id
s. En VIM, con el cursor en la definición def
, hacer esto::s/id id/id . id ./g
.Respuestas:
Sabemos el tipo de
id
,Y cuando nos especializamos en esto
id id
, la copia izquierda deid
tiene el tipo:Y luego, cuando usted se especializa esto de nuevo para el extremo izquierdo
id
enid id id
, se obtiene:Para que vea cada uno
id
que agrega, la firma de tipo del extremo izquierdoid
es dos veces más grande.Tenga en cuenta que los tipos se eliminan durante la compilación, por lo que esto solo ocupará memoria en GHC. No ocupará memoria en su programa.
fuente
id
se repiten
veces, el espacio de su tipo es proporcional a2^n
. El tipo inferido en el código de Ryan necesitaría2^27
referencias a su variable de tipo además de la otra estructura necesaria para representar el tipo, que probablemente sea mucho más grande de lo que esperaría que fueran la mayoría de los tipos.