Проверьте запуском
LISPEX
(reduce + 0 (map (lambda (x) (* x x)) (filter odd? (list 1 2 3 4))))Наблюдаемый результат
OUTPUT
10Разберите приём
- Отберите.
filterсохраняет1и3, для которыхodd?истинен. - Преобразуйте.
mapвозводит оставшиеся значения в квадрат и получает(1 9)в том же порядке. - Сверните.
reduceначинает с0, складывает квадраты и получает10.
Как рассуждать
- Используйте
mapдля одного результата на элемент,filterдля выбора и folds для одного аккумулятора. - Используйте
all?илиany?, если строгий boolean позволяет остановить обход раньше. - Callbacks выполняются как гостевые процедуры, поэтому действуют ошибки, escapes, предупреждения и value contexts.
string-mapиvector-mapсоздают новые коллекции; вариантыfor-eachвыполняют только эффекты и возвращают ноль значений.- Используйте
apply, когда последний правильный список должен стать позиционными аргументами; хвостовое применение сохраняется.
Проверьте себя
Что вернёт тот же конвейер, если заменить odd? на even??
Ответ
Он оставит 2 и 4, преобразует их в (4 16) и вернёт 20.
Частая ошибка
Callback, дающий ноль или несколько значений в позиции одного значения, вызывает E320.
Куда дальше
Точная арность callback указана в справочнике. Используйте рекурсию, если поддерживаемые комбинаторы не выражают обход ясно.