Основная идея состоит в том, что все три являются способами применения некоторой функции ко всем элементам списка.
Карта, пожалуй, самая простая — вы просто применяете функцию к каждому элементу списка. Это в основном то же самое, что и цикл for-each в других языках:
(map (lambda (x) (+ x 1)) '(1 2 3))
=> (2 3 4)
По сути, карта такая: (map f '(1 2 3))
совпадает с (list (f 1) (f 2) (f 3))
.
Фильтр также прост: функция действует как арбитр, решая, сохранять ли каждое число. Представьте себе очень разборчивого едока, просматривающего меню и ноющего о вещах, которые он не будет есть ;)
(filter (lambda (x) (equal? x 1)) '(1 2 3))
=> (1)
Мне кажется, фолд труднее всего понять. Более интуитивно понятным названием было бы «накопить». Идея состоит в том, что вы «комбинируете» список по мере продвижения. В повседневном использовании есть некоторые функции, которые на самом деле являются сгибами — sum — прекрасный пример.
(foldr + 0 '(1 2 3))
=> 6
Вы можете думать о сгибе как о том, что вы берете функцию и помещаете ее между каждым элементом в списке: (foldr + 0 '(1 2 3))
совпадает с 1 + 2 + 3 + 0
.
Fold особенный, потому что, в отличие от двух других, он обычно возвращает скалярное значение — то, что было элементом списка, а не самим списком. (Это не всегда верно, но все равно подумайте об этом сейчас.)
Обратите внимание, что я, возможно, не довел до совершенства каждую деталь кода — я когда-либо использовал только другую, более старую реализацию Scheme, поэтому я мог упустить некоторые детали Racket.
person
Tikhon Jelvis
schedule
24.10.2011