Вопрос о фолд-функции в ракетке. (Функциональное программирование) - PullRequest
2 голосов
/ 31 января 2020

Итак, у меня есть эта строка кода:

(foldl cons '() '(1 2 3 4))

И вывод, который я получаю при запуске, таков:

'(4 3 2 1)

Не могли бы вы объяснить мне, почему я не получаю '(1 2 3 4) вместо этого?

Я прочитал документацию, но все еще немного озадачен тем, как работает foldl. Также, если бы я хотел определить foldl как бы я указал в Racket, что функция может принимать переменное количество списков в качестве аргументов?

Спасибо!

1 Ответ

4 голосов
/ 31 января 2020

Да. По определению левой складки функция объединения вызывается с первым элементом списка и с накопленным результатом на данный момент , и результат этого вызова передается (как новый (обновил накопленный результат) до рекурсивного вызова foldl с той же функцией объединения и остальной частью списка:

(foldl  cons                          <b>'()</b>   '(1 2 3))
=
(foldl  cons                  <b>(cons 1</b> '()<b>)</b>    '(2 3))
=
(foldl  cons          <b>(cons 2</b> (cons 1 '())<b>)</b>     '(3))
=
(foldl  cons  <b>(cons 3</b> (cons 2 (cons 1 '()))<b>)</b>     '())
=
              (cons 3 (cons 2 (cons 1 '())))

И когда список пуст, накопленный результат пока возвращается в качестве окончательного результата.

К вашему второму вопросу, функции variadi c в схеме указываются с точкой . в списке аргументов, например:

(define (fold-left f acc <b>. lists</b>)
  (if (null? (first <b>lists</b>))            ;; assume all have same length
      acc
      (apply fold-left                 ;; recursive call
             f
             (apply f  (append (map first <b>lists</b>)   ;; combine first elts
                               (list acc)))        ;;  with result so far
             (map rest <b>lists</b>))))       ;; the rests of lists

Действительно,

(fold-left (lambda (a b result)
             (* result (- a b)))
           1
           '(1 2 3)
           '(4 5 6))

возвращает -27.

...