web-dev-qa-db-fra.com

Quelle est la différence entre la carte et appliquer dans le schéma?

J'essaie d'apprendre Scheme et j'ai du mal à comprendre la différence entre map et apply.

Si je comprends bien, map applique la fonction à chaque élément de la liste, et apply applique quelque chose aux arguments d'une procédure.

Peuvent-ils être utilisés de manière interchangeable?

16
Sarah

Ils ne sont pas les mêmes! Leurs noms peuvent en fait aider à se rappeler qui fait quoi.

map prendra comme argument une procédure et une ou plusieurs listes. La procédure sera appelée une fois pour chaque position des listes, en utilisant comme arguments la liste des éléments à cette position:

(map - '(2 3 4))
; => (-2 -3 -4)

map appelé (- 2), (- 3), (- 4) pour construire la liste.

(map + '( 1  2  3)
       '(10 20 30))
; => (11 22 33)

map appelé (+ 1 10)(+ 2 20)(+ 3 30) pour construire la liste.

(map * '(2 2 -1)
       '(0 3  4)
       '(5 4  2))
; => (0 24 -8)

map appelé (* 2 0 5)(* 2 3 4)(* -1 4 2) pour construire la liste.

map porte ce nom car il implémente une "map" (fonction) sur un ensemble de valeurs (dans les listes):

(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 prendra au moins deux arguments, le premier étant une procédure et le dernier une liste. Il appellera la procédure avec les arguments suivants, y compris ceux de la liste:

(apply + '(2 3 4))
; => 9

C'est la même chose que (+ 2 3 4)

(apply display '("Hello, world!"))
; does not return a value, but prints "Hello, world!"

C'est la même chose que (display "Hello, world!").

apply est utile lorsque vous avez des arguments sous forme de liste,

(define arguments '(10 50 100))
(apply + arguments)

Si vous essayez de réécrire la dernière ligne sans utiliser apply, vous vous rendrez compte que vous devez parcourir la liste en sommant chaque élément ...

apply peut également être utilisé avec plus de ces deux arguments. Le premier argument doit être un objet appelable (une procédure ou une continuation). Le dernier doit être une liste. Les autres (entre le premier et le dernier) sont des objets de tout type. Donc, appeler

(apply PROC a b c ... y z '(one two ... twenty))

équivaut à appeler

(PROC a b c ... y z  one two ... twenty)

Voici un exemple concret:

(apply + 1 -2 3 '(10 20))
; => 32

C'est la même chose que (+ 1 -2 3 10 20)

apply porte ce nom car il vous permet "d'appliquer" une procédure à plusieurs arguments.

42
Jay

Non, apply appelle son premier argument comme une procédure, avec tous les autres comme arguments, avec le dernier - liste - ouvert, c'est-à-dire son contenu "découpé en tranches":

(apply f a b (list c d e)) == (f a b c d e)

Par exemple.:

(appliquer + 1 2 (liste 3 4 5))
; Valeur: 15

Ce n'est qu'un appel; map appelle en effet son premier argument pour chaque élément membre de son deuxième argument.

Une utilisation combinée de map et apply est la fameuse astuce transpose:

(appliquer la liste des cartes '((1 2 3) (10 20 30)))
; Valeur: ((1 10) (2 20) (3 30))

3
Will Ness

Comme l'a suggéré la première réponse, map

La procédure sera appelée une fois pour chaque position des listes, en utilisant comme arguments la liste des éléments à cette position

En revanche, apply

(apply function argument-list)

passer des arguments dans argument-list à function à la fois. Donc function n'est appelé qu'une seule fois.

0
GraceMeng