Recursão implícita na lista preguiçosa de haskell funky
No Haskell, você pode criar listas infinitas devido à preguiça:
Prelude> let g = 4 : g
Prelude> g !! 0
4
Prelude> take 10 g
[4,4,4,4,4,4,4,4,4,4]
Agora, o que exatamente acontece quando tento construir uma lista como essa?
Prelude> let f = f !! 10 : f
Prelude> f !! 0
Interrupted.
Prelude> take 10 f
[Interrupted.
Prelude>
oInterrupted.
s estou pressionando CTRL + C depois de esperar alguns segundos. Parece entrar em um loop infinito, mas por que é esse o caso?
Explicação para não-Haskellers:
o:
operador éprepend
:
Prelude> 4 : [1, 2, 3]
[4,1,2,3]
Está linha:
Prelude> let g = 4 : g
diz "deixeg
ser a lista construída anexando4
na listag
". Quando você solicita o primeiro elemento, 4 é retornado, pois já está lá. Quando você solicita o segundo elemento, ele procura o elemento após 4. Esse elemento seria o primeiro elemento da listag
, que acabamos de calcular (4), então4
é retornado. O próximo elemento é o segundo elemento deg
, que novamente calculamos, etc ...
!!
é apenas indexar em uma lista, então isso significa obter o elemento no índice0
deg
:
Prelude> g !! 0
4
Mas quando eu faço isso:
Prelude> let f = f !! 10 : f
algo quebra, porque para calcular o primeiro elemento def
você precisa do 11º elemento, que ainda não existe? Eu esperaria uma exceção, porém, não um loop infinito ...