Haskell tem uma função de identidade que retorna a entrada inalterada. A definição é simples:
id :: a -> a
id x = x
Então, para se divertir, isso deve resultar 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
Após alguns segundos (e cerca de 2 gb de memória de acordo com o Gerenciador de Tarefas), a compilação falha com ghc: out of memory
. Da mesma forma, o intérprete diz ghci: out of memory
.
Como id
é uma função muito simples, não esperaria que fosse uma carga de memória em tempo de execução ou tempo de compilação. Para que toda a memória está sendo usada?
id
s. No VIM, com o cursor sobre a definição def
, faça o seguinte::s/id id/id . id ./g
.Respostas:
Sabemos o tipo de
id
,E quando nos especializamos nisso
id id
, a cópia esquerda deid
tem tipo:E então quando você se especializar isso de novo para o mais à esquerda
id
emid id id
, você obtém:Assim, você verá que cada um que
id
você adiciona, a assinatura de tipo da extremidade esquerdaid
é duas vezes maior.Observe que os tipos são excluídos durante a compilação, portanto, isso ocupará apenas memória no GHC. Não vai ocupar memória em seu programa.
fonte
id
for repetidon
vezes, o espaço de seu tipo é proporcional a2^n
. O tipo inferido no código de Ryan precisaria de2^27
referências à sua variável de tipo, além da outra estrutura necessária para representar o tipo, que provavelmente é muito maior do que você esperaria que a maioria dos tipos fosse.