2014-12-15 6 views
9

Ich versuche, Scheme zu lernen, und mir fällt es schwer, den Unterschied zwischen map und apply zu verstehen.Was ist der Unterschied zwischen map und apply im Schema?

Wie ich verstehe, wendet map die Funktion auf jedes Element der Liste an, und apply wendet etwas auf die Argumente einer Prozedur an.

Können sie austauschbar verwendet werden?

Antwort

21

Sie sind nicht gleich! Ihre Namen können tatsächlich helfen, sich daran zu erinnern, was was macht.

map wird als Argument eine Prozedur und eine oder mehrere Listen nehmen. Das Verfahren wird einmal für jede Position der Listen aufgerufen werden, als Argument der Liste der Elemente in dieser Position mit:

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

map(- 2) genannt, (- 3), (- 4) die Liste zu erstellen.

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

map genannt (+ 1 10)(+ 2 20)(+ 3 30) die Liste zu erstellen.

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

map genannt (* 2 0 5)(* 2 3 4)(* -1 4 2) die Liste zu erstellen.

map hat diesen Namen, weil es eine „Karte“ (Funktion) auf eine Reihe von Werten (in den Listen) implementiert:

(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 wird mindestens zwei Argumente, die erste von ihnen ist eine Prozedur und die letzte eine Liste.Es wird das Verfahren mit den folgenden Argumenten aufrufen, einschließlich derjenigen in der Liste:

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

Dies ist die gleiche wie (+ 2 3 4)

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

Dies ist die gleiche wie (display "Hello, world!") ist.

apply ist nützlich, wenn Sie Argumente als Liste,

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

Wenn Sie versuchen, die letzte Zeile neu zu schreiben, ohne apply zu verwenden, werden Sie feststellen, dass Sie eine Schleife über die Liste zu müssen jedes Element summiert werden. ..

apply kann auch mit mehr als diesen beiden Argumenten verwendet werden. Das erste Argument muss ein aufrufbares Objekt sein (eine Prozedur oder eine Fortsetzung). Der letzte muss eine Liste sein. Die anderen (zwischen dem ersten und dem letzten) sind Objekte eines beliebigen Typs. So rufen

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

ist die gleiche wie

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

Hier ist ein konkretes Beispiel nennen:

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

Dies ist die gleiche wie (+ 1 -2 3 10 20)

apply hat diesen Namen, weil es erlaubt Sie können eine Prozedur auf mehrere Argumente anwenden.

+1

In Schema 'apply' wird eine beliebige Anzahl von Argumenten verwendet, aber das erste muss etwas aufrufbar sein (Prozedur oder Fortsetzung) und das letzte muss eine Liste sein. Die Argumente dazwischen sind die ersten Argumente .. '(apply map list '((abc) (1 2 3))) => ((a 1) (b 2) (c 3))' – Sylwester

+0

@Sylwester: ja, Ich habe den Beitrag bearbeitet. Vielen Dank! – Jay

+1

Ein weiterer wichtiger Unterschied ist, dass die Karte immer eine Liste zurückgibt. –

3

Nein, apply nennt ihr erstes Argument als ein Verfahren, mit dem ganzen Rest als Argument, mit der letzten - Liste - geöffnet, dh seinen Inhalt „in Scheiben geschnitten in“:

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

ZB:

(anwenden + 1 2 (3 4 5))
; Wert: 15

Es ist nur ein Anruf; map ruft tatsächlich sein erstes Argument für jedes Elementelement seines zweiten Arguments auf.

Eine kombinierte Verwendung von map und apply ist der berühmte transpose Trick:

(Karte Liste ‚((1 2 3) (10 20 30)) gilt)
; Wert: ((1 10) (2 20) (3 30))

Verwandte Themen