Может кто-нибудь объяснить мне следующее выражение Haskell - PullRequest
9 голосов
/ 04 января 2011
f :: Integer -> Integer -> [Integer]
f i n = n : f (i+2) (n+i)

Может кто-нибудь объяснить мне, что он делает.я знаю, что это возвращает [0,1,4,9,16 ..], но я не понимаю, как и что n : f означает

Ответы [ 2 ]

10 голосов
/ 04 января 2011

: является оператором «cons» и создает новый список, заголовок которого является значением слева от оператора, а хвост - значением справа от оператора.Таким образом, 0 : [1, 2, 3] является списком [0, 1, 2, 3].

Проверьте поведение этой функции, оценив f 1 0 следующим образом:

f 1 0 = 0 : f 3 1

т.е. f 1 0 является результатом созданияновый список, состоящий из 0 в заголовке и списка, возвращаемого f 3 1 в качестве хвоста.Аналогично, f 3 1 выглядит следующим образом:

f 3 1 = 1 : f 5 4

т.е. f 3 1 является результатом создания нового списка, состоящего из 1 в заголовке и списка, возвращаемого f 5 4 в качестве хвоста.

Таким образом, функция рекурсивно создает список.Кроме того, он бесконечно хвостовой рекурсивен (поскольку не имеет завершающего условия) и, следовательно, приведет к бесконечно длинному списку.

Что касается начальной строки, f :: Integer -> Integer -> [Integer], это означает, что fфункция, которая принимает два целых числа (Integer -> Integer) и возвращает список целых чисел ([Integer]).Строго говоря, f принимает целое число (Integer) и возвращает другую функцию, которая принимает целое число и возвращает список целых чисел (Integer -> [Integer]) как результат каррирования функции.С этой концепцией вы познакомитесь, углубившись в изучение языка Haskell и других функциональных языков программирования.

5 голосов
/ 04 января 2011

Код в вашем вопросе ничего не делает, потому что он содержит ошибку типа и синтаксическую ошибку.

f :: Integer -> Integer --> [Integer]

Как видно из выделения, последний бит является комментарием, поскольку -- запускает комментарийв Хаскеле.Как следствие, объявленный тип f равен Integer -> Integer, что неверно.Чтобы исправить это изменение --> на ->.

f i n = n : f (i+2) (n+i]

Здесь у вас есть открытие ( и затем закрытие ].Очевидно, что это неправильно.Чтобы исправить это изменение (n+i] на (n+i).

Теперь, когда это сделано, вот что делает фиксированный код:

: - конструктор для типа списка.x : xs - это список, в котором x является его головой, а xs - его хвостом.n : f (i+2) (n+i) анализируется как n : (f (i+2) (n+i)) (не (n : f) (i+2) (n+1), как вы, кажется, верите).Таким образом, он создает список, голова которого равна n, а его хвост - результат f (i+2) (n+1).

...