Бесконечный цикл на Haskell с простым повторным действием - PullRequest
3 голосов
/ 22 марта 2012

У меня есть такой код:

Prelude> let n = [1,2,3,4]
Prelude> n
[1,2,3,4]
Prelude> 0:n
[0,1,2,3,4]
Prelude> let n = 0:n

И когда я набираю интерпретатор Haskell после верхнего:

Prelude> n

Я получаю бесконечный результат:

[0,0,0,0,0,0,0,0,0

А где печать "0" бесконечна.

Почему я получаю такой результат?
Есть ли какие-то рекурсивные вещи, и почему / как это работает на уровне переводчика?
Могу ли я отловить переполнение стека, что такое на GHCi или нет?

Спасибо,
С наилучшими пожеланиями!

Ответы [ 3 ]

8 голосов
/ 22 марта 2012

Новое связывание n затеняет старое.Вы не переназначаете переменные в Haskell.

7 голосов
/ 22 марта 2012

Джош говорит, что ваше определение n расширяется как:

0:n.  -- note n still equals 0:n, just like you said
0:0:n. -- note n _still_ equals 0:n
0:0:0:n
...
1 голос
/ 22 марта 2012

Haskell's let похож на letrec в других языках, таких как ML: привязки могут быть рекурсивными. Другими словами, n = 0:n определяет n как список, где первый элемент равен 0, а остальная часть списка равна n. Это означает, что второй элемент n равен первому элементу n, который равен 0 и т. Д.

Бесконечные списки в Хаскеле в порядке из-за лени. Если вы когда-либо используете только первые 10 элементов списка, то одиннадцатый элемент и далее никогда не будут оцениваться.

...