Здесь можно проверить, как процедура обхода вызывает переданную вами процедуру и сколько значений ожидает в ответ. Здесь же описано, как apply передаёт аргументы из списка.
Постройте список справа налево
Запустите этот полный пример на площадке.
(fold-right cons (list) (list 1 2 3))Результат
(1 2 3)fold-right начинает с пустого списка и посещает 3, 2, затем 1. При вызове cons текущий элемент становится первым аргументом, а накопленный список — вторым. Каждый вызов добавляет элемент в начало, поэтому итоговый список равен (1 2 3).
Процедура обратного вызова — это процедура, которую вы передаёте для вызова при обходе. Накопленный результат переносится с одного шага на следующий.
Проверьте вызовы и возвращаемые значения
Каждая процедура обхода принимает одну коллекцию. Аргумент-список должен быть правильным: его конечный хвост — пустой список.
В таблице proc и predicate обозначают переданную процедуру. Предикат проверяет, удовлетворяет ли элемент условию. Обход идёт слева направо, кроме fold-right.
| Вызов | Вызов переданной процедуры | Требования к её результату и общий результат |
|---|---|---|
(map proc list) | (proc element) | ровно одно значение за вызов; значения собираются в новый список |
(filter predicate list) | (predicate element) | ровно одно значение за вызов; элемент сохраняется, если это значение не #f |
(all? predicate list), (any? predicate list) | (predicate element) | ровно одно #t или #f за вызов; возвращает булево значение, как только ответ известен |
(reduce proc init list), (fold-left proc init list) | (proc accumulator element) | ровно одно значение за вызов становится следующим накопленным результатом; возвращает итоговый результат |
(fold-right proc init list) | (proc element accumulator) | обход справа налево; ровно одно значение за вызов становится следующим накопленным результатом; возвращает итоговый результат |
(string-map proc string) | (proc character) | ровно один символ за вызов; возвращает новую строку |
(vector-map proc vector) | (proc element) | ровно одно значение за вызов; возвращает новый вектор |
(for-each proc list), (string-for-each proc string), (vector-for-each proc vector) | (proc element) | отбрасывает любое число возвращённых значений; сама возвращает ноль значений |
reduce и fold-left — одна и та же процедура. Свёртки начинают накопление с init и возвращают его без изменений для пустого списка.
Элементы строки или вектора копируются до первого обратного вызова. Поэтому изменение исходного вектора во время обхода не меняет посещаемые элементы.
Интерпретатор сам вызывает переданную процедуру. Ошибки, предупреждения и выходы через одноразовые продолжения подчиняются обычным правилам вызова в Лиспексе. Такие выходы описаны на странице о продолжениях.
Вызовите процедуру один раз через apply
(apply proc arg ... final-list) вызывает proc один раз. Сначала передаются явно указанные значения arg, затем элементы final-list. Последний список должен быть правильным.
apply сохраняет все значения, возвращённые proc. В хвостовой позиции вызов proc не оставляет дополнительного кадра возврата. Подробнее — на странице о хвостовых вызовах.
Найдите причину ошибки
| Ошибка | Что проверить |
|---|---|
E302 | Число аргументов внешней процедуры и процедуры обратного вызова. Сопоставьте оба вызова с таблицей. Для apply сложите число явных аргументов и элементов последнего списка. |
E320 | Процедура обратного вызова вернула ноль или несколько значений там, где таблица требует одно. Возвращайте одно значение. Для действий вроде печати используйте вариант for-each. |
E312 | Проверьте тип коллекции и требование правильного списка. Для all? и any? возвращайте булево значение, для string-map — символ. |
Руководство объединяет отбор, преобразование и накопление в одном примере. Другие встроенные процедуры перечислены в указателе.