В чем разница между 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))