Понимание fibonacci Haskell

fibs :: [Int]
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]

Это генерирует последовательность Fibonacci.

Я понимаю поведение защиты, :, zip и tail, но я не понимаю <-. Что это делает здесь?

15
задан hlovdal 26 December 2010 в 19:32
поделиться

5 ответов

Из-за большого количества голосов я превратил свой комментарий в ответ.

То, что вы видите, не является защитой, но это понимание списка. Для начала подумайте, что это способ выразить математическую нотацию множества, например A = { x | x элемент N }, что означает примерно следующее: Множество A - это множество всех натуральных чисел. При понимании списка это будет [x | x <- [1...] ].

Вы также можете использовать ограничения на числа: [x | x <- [1...], x `mod` 2 == 0 ] и многое другое.

Существует множество хороших учебников по haskell, посвященных пониманию списков, и даже вопрос на StackOverflow о ресурсах haskell.

15
ответ дан 1 December 2019 в 01:23
поделиться

Единственная сложность - это молнии (хвосты) . zip просто составляет попарный список из каждого из своих аргументов. Итак, если у вас есть два таких списка:

[ 1, 2, 3, 4 ]
[ "a", "b", "c", "d" ]

Их заархивирование приведет к:

[ (1,"a"), (2,"b"), (3,"c"), (4,"d") ]

Стрелка влево (назначение в шаблон деструктуризации) просто извлекает парные элементы, чтобы их можно было сложить вместе. Два архивируемых списка - это fibs и (tail fibs) - другими словами, последовательность Фибоначчи и последовательность Фибоначчи, смещенная на 1 элемент. Haskell оценивается лениво, поэтому он может вычислить список для любого необходимого количества элементов. Это относится и к zip.

11
ответ дан 1 December 2019 в 01:23
поделиться

Понимание списка в скобках:

[ a + b | (a, b) <- zip fibs (tail fibs)]

возвращает список, содержащий результат (a + b), где переменные a и b получены в результате

zip fibs (tail fibs)
1
ответ дан 1 December 2019 в 01:23
поделиться

Давайте расширим его.

zip создает пары из содержимого двух списков. Итак, первая пара застежек-молний (хвостов) дает нам (0, 1) , что в сумме дает 1. Итак, теперь список [0,1, 1] . Теперь мы знаем три элемента в списке, поэтому понимание списка может продолжаться, захватывая следующий элемент из списка и следующий элемент из хвоста, что дает (1,1) - сложенные вместе, что дает 2 Затем мы получаем следующую пару, которая равна (1,2) , что составляет следующее число в последовательности 3. Это может продолжаться бесконечно, так как понимание всегда будет обеспечивать достаточное количество элементов.

4
ответ дан 1 December 2019 в 01:23
поделиться

Для чего это стоит, мне легче понять следующую версию:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
2
ответ дан 1 December 2019 в 01:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: