В чем разница между map и apply in scheme?
Я пытаюсь изучить схему, и мне трудно понять разницу между map и apply.
как я понимаю, map применяет функцию к каждому элементу списка, и apply что касается аргументов процедуры.
можно ли их использовать взаимозаменяемо?
2 ответов
они не то же самое! Их имена могут помочь вспомнить, кто что делает.
map будет принимать в качестве аргумента одну процедуру и одного или нескольких списков.
Процедура будет вызываться один раз для каждой позиции списков, используя в качестве аргументов список элементов на этой позиции:
(map - '(2 3 4))
; => (-2 -3 -4)
map под названием (- 2), (- 3), (- 4) для создания списка.
(map + '( 1 2 3)
'(10 20 30))
; => (11 22 33)
map под названием (+ 1 10) (+ 2 20) (+ 3 30) построить список.
(map * '(2 2 -1)
'(0 3 4)
'(5 4 2))
; => (0 24 -8)
map под названием (* 2 0 5) (* 2 3 4) (* -1 4 2) для создания списка.
map имеет это имя, потому что оно реализует "карту" (функцию) на наборе значений (в списках):
(map - '(2 3 4))
arguments mapping "-" result
2 === (- 2) ===> -2
3 === (- 3) ===> -3
4 === (- 4) ===> -4
(map + '( 1 2 3)
'(10 20 30))
arguments mapping "+" result
1 10 === (+ 1 10) ===> 11
2 20 === (+ 2 20) ===> 22
3 30 === (+ 3 30) ===> 33
apply примет по меньшей мере два аргументы, первый из которых является процедурой, а последний-списком. Он вызовет процедуру со следующими аргументами, в том числе внутри списка:
(apply + '(2 3 4))
; => 9
это то же самое, что (+ 2 3 4)
(apply display '("Hello, world!"))
; does not return a value, but prints "Hello, world!"
это то же самое, что (display "Hello, world!").
apply полезно, когда у вас есть аргументы в виде списка
(define arguments '(10 50 100))
(apply + arguments)
если вы попытаетесь переписать последнюю строку без использования apply, вы поймете, что вам нужно перебирать список, суммируя каждый элемент...
apply может также использоваться с более чем этими двумя аргументами. Первым аргументом должен быть вызываемый объект (процедура или продолжение). Последний должен быть список. Остальные (между первым и последним) являются объектами любого типа. Так зовет
(apply PROC a b c ... y z '(one two ... twenty))
это то же самое, что и вызов
(PROC a b c ... y z one two ... twenty)
вот конкретный пример:
(apply + 1 -2 3 '(10 20))
; => 32
это то же самое, что (+ 1 -2 3 10 20)
apply имеет это имя, потому что оно позволяет "применить" процедуру к нескольким аргументам.
нет, apply вызывает свой первый аргумент как процедуру, со всеми остальными в качестве аргументов, с последним-list-открытым, т. е. его содержимое "нарезано":
(apply f a b (list c d e)) == (f a b c d e)
например:
(применить + 1 2 (Список 3 4 5))
;Стоимость: 15
это всего лишь один звонок;map зовет своего первого аргумента для каждого элемента своего второго аргумента.
одно комбинированное использование map и apply знаменитый transpose трюк:
(применить карту список '((1 2 3) (10 20 30)))
;Значение: ((1 10) (2 20) (3 30))