Я пытаюсь выучить меня Haskell (для большого блага), и одна из многих других вещей, которые я делаю, пытается решить некоторые проблемы Project Euler, когда я собираюсь проверить свой характер.
Выполняя некоторые из проблем, связанных с Фибоначчи, я наткнулся и начал играть с рекурсивной версией бесконечного списка последовательности Фибоначчи:
fibs = 1 : 2 : zipWith (+) fibs (tail fibs)
Для одной из проблем PE мне нужно было извлечь подпоследовательность даже чисел Фибоначчи менее 4 000 000. Я решил сделать это со списком, и в моей игре с кодом я наткнулся на то, что я не совсем понимаю; Я предполагаю, что это мое слабое понимание на ленивой схеме оценки Haskell, которая усложняет ситуацию.
Следующее понимание прекрасно работает:
[x | x <- takeWhile (<= 4000000) fibs, even x]
Следующее понимание вращается навсегда; поэтому я прошел через и вернул выход в stdout, и пока он останавливается в правильном месте, он просто продолжает оценивать рекурсивно определенный список навсегда, не заканчивая после достижения закрытого значения; что последний элемент в списке печатается с запятой, но нет других элементов списка или закрывающей квадратной скобки:
[x | x <- fibs, x <= 4000000, even x]
Итак, что же такое секретный соус, используемый различными функциями, которые хорошо играют с бесконечными списками?