2015-07-27 2 views
7

Я играю с языком, чтобы начать учиться, и я озадачен своим умом о том, как работает рекурсивное определение.Как работает (co) рекурсивное определение в Haskell?

Например, давайте рассмотрим последовательность треугольных чисел (TN n = sum [1..n])

Решение, предложенное было:

triangularNumbers = scanl1 (+) [1..] 

До сих пор, так хорошо.

Но решение я придумал было:

triangularNumbers = zipWith (+) [1..] $ 0 : triangularNumbers 

Что тоже правильно.

Теперь мой вопрос: как это перевести на более низкую реализацию уровня? Что происходит именно за сценой, когда такое рекурсивное определение выполняется?

+0

Возможно, это было задано и ответили ранее, но поиск «рекурсивного определения» вызывает только вопросы, связанные с рекурсией в алгоритмическом смысле. –

+0

[это] (https://hackhands.com/lazy-evaluation-works-haskell/) может помочь. – Alec

+0

Начните с понимания '[1 ..]'. –

ответ

5

Вот простая рекурсивная функция, которая дает вам п-е треугольное число:

triag 0 = 0 
triag n = n + triag (n-1) 

Ваше решение triag' = zipWith (+) [1..] $ 0 : triag' нечто большее фантазии: Это corecursive (click, click). Вместо вычисления n-го числа, уменьшая его до значения меньших входных данных, вы определяете всю бесконечную последовательность треугольных чисел, рекурсивно определяя следующее значение, учитывая начальный сегмент.

Как Haskell обрабатывает такую ​​конструкцию? Когда он встречает ваше определение, вычисления не выполняются, оно откладывается до тех пор, пока результаты не потребуются для дальнейших вычислений. Когда вы обращаетесь к определенному элементу своего списка triag', Haskell начинает вычислять элементы списка на основе определения, вплоть до элемента, к которому обращаются. Для более подробной информации я нашел this статью об ленивой оценке полезной. Таким образом, ленивая оценка отлично подходит, если вам не нужно прогнозировать использование памяти.

Here - аналогичный вопрос SO, с пошаговым объяснением оценки fibs = 0 : 1 : zipWith (+) fibs (tail fibs), корекурсивным определением последовательности Фибоначчи.

+0

Но где основной случай в определение, которое я представил в качестве примера? Требуется ли это от 1 от [1 ..] и 0 от 0: tn? –

+1

Предположим, вы получили доступ к первому элементу 'triag'': его можно вычислить напрямую, это' 1 + 0', сумма первых элементов '[1 ..]' и '0: triag''. Теперь второе: это '2 + 1', где' 2' - это второй элемент из '[1 ..]' и '1' второй элемент' 0: triag'', т. Е. Является первым элементом 'traag '', 1. Таким образом, любой элемент' triag'' определяется вашим решением и может быть вычислен по мере необходимости. – lodrik

Смежные вопросы