Понимание шаблона карты для n-арных операций над n списками в Scheme
Я это понимаю (map f '(a b c d))
является '(f(a) f(b) f(c) f(d))
применяя функцию f
каждому элементу в списке. Но мне трудно понять следующее:
(map * '(1 2) '(1 2))
Выход должен быть '(1 4)
, Как так?
Может кто-нибудь объяснить, как map
шаблон работает в Scheme, когда мы применяем n-ную операцию к n спискам?
3 ответа
map
берет i-ые элементы предоставленных списков, передает их в n-арную операцию и сохраняет результат в i-й позиции возвращенного списка.
Так, (map f '(a b c d) '(A B C D))
будет равен ((f a A) (f b B) (f c C) (f d D))
, Более двух списков обрабатываются аналогично.
Чтобы действительно понять что-то лучше всего реализовать это самим.
Карта для функций с 1 аргументом проста, это
(define (map1 f1 xs)
(cons (f1 (car xs))
(map1 f1
(cdr xs))))
(добавление базового варианта оставлено в качестве упражнения). Аналогично для двоих,
(define (map2 f2 xs ys)
(cons (f2 (car xs) (car ys))
(map2 f2
(cdr xs) (cdr ys))))
и три,
(define (map3 f3 xs ys zs)
(cons (f3 (car xs) (car ys) (car zs))
(map3 f3
(cdr xs) (cdr ys) (cdr zs))))
Мы можем использовать один и тот же шаблон для любой n- аргументной функции, которая должна быть отображена на любые n списков, чтобы получить n аргументов из:
map_n:
xs: x1 x2 x3 x4 x5 ...
ys: y1 y2 y3 y4 y5 ...
zs: z1 z2 z3 z4 z5 ...
...........................
↓ ↓ ↓ ↓ ↓
f f f f f
= = = = =
results: r1 r2 r3 r4 r5 ...
- связанные: умножение матриц в схеме, список списков
'(f (a) f (b) f (c) f (d))
есть и может быть только (f (a) f (b) f (c) f (d))
после оценки.
map
для одного списка аргумент может быть определен так:
(define (map1 fn lst)
(if (null? lst)
'()
(cons (fn (car lst))
(map1 fn (cdr lst)))))
а также (map add1 '(1 2 3))
можно заменить на
(cons (add1 '1)
(cons (add1 '2)
(cons (add1 '3)
'())))
; ==> (2 . (3 . (4 . ())))
; ==> (2 3 4)
Сейчас map
принимает по крайней мере один аргумент списка и ожидает, что переданная функция принимает один или каждый. таким образом (map * '(1 2) '(1 2))
такой же как:
(cons (* '1 '1)
(cons (* '2 '2)
'()))
; ==> (1 . (4 . ()))
; ==> (1 4)
Я не совсем уверен, если у вас возникли проблемы с пониманием map
или как составляются списки. Если это последнее, вы должны сделать это главным приоритетом, чтобы иметь возможность видеть (1 2 (3 4))
и понимаю, что 3
это caaddr
так как пары (1 . (2 . ((3 . (4 . ())) . ())))
, Прочтите это справа налево, глядя на пары, и вы увидите это. Если это map
тогда вам нужно их реализовать. Это лучший способ узнать это.