Hinzufügen eines Elements zu List in Scheme

7

Unten ist mein Code, der ein Auto-Element einer Liste (carVal) und eine Liste (initialisiert als leer) als Parameter annimmt. Ich möchte das Element an die Liste anhängen, aber das gleiche funktioniert nicht.

%Vor%

Das Display zeigt die ganze Zeit eine leere Liste () . Kann mir jemand helfen, warum zu verstehen?

    
name_masked 03.07.2010, 20:19
quelle

5 Antworten

21

Nun, es gibt append! als primitives Element, das die meisten Ihrer Probleme löst, wie bereits erwähnt, Schema neigt dazu, die Mutation zu missbrauchen, ist zwar möglich, wird aber normalerweise vermieden, sodass alle Prozeduren, die mutieren, ein ! haben. (genannt ein Knall) an ihrem Ende.

Auch set! mutiert keine Daten, es ändert eine Umgebung , es macht eine Variable auf eine andere Sache, die ursprünglichen Daten bleiben unverändert.

Das Mutieren von Daten in Scheme ist ziemlich beschwerlich, aber um Ihnen meine eigene Implementierung von append! um zu sehen, wie es gemacht wird:

%Vor%

Beachten Sie die Verwendung von set-cdr! , das ein echter Mutator ist, es funktioniert nur bei Paaren, es mutiert Daten im Speicher, im Gegensatz zu 'set!'. Wenn ein Paar an eine Funktion übergeben und mit set-cdr mutiert wird! oder Set-Car !, es ist überall im Programm mutiert.

Dies gehorcht dem SRFI append! spec, die besagt, dass es variadic sein sollte und dass es beispielsweise einen undefinierten Wert zurückgeben soll.

%Vor%

Was anzeigt:

%Vor%

Wie sichtbar, anhängen! kann eine unendliche Anzahl von Argumenten annehmen und es mutiert sie alle bis auf die letzten.

Scheme ist vielleicht nicht die ideale Sprache für Sie. Die Verwendung von append! Wie bereits erwähnt, ist nicht standardisiert, stattdessen wird append bevorzugt, das nicht mutiert und für seinen Rückgabewert aufgerufen wird. Was ich als solches implementiere:

%Vor%

Dies zeigt einen vertrauteren Scheme-Stil in Abwesenheit von Mutation, starker Rekursion und keine Verwendung der Sequenzierung.

Edit: Wenn Sie nur einige Elemente zu einer Liste hinzufügen wollen und nicht per se zwei verbinden:

%Vor%

Was macht was Sie erwarten

    
Zorf 05.07.2010, 03:06
quelle
5
  1. append erstellt eine neue Liste, sie ändert keine bestehende Liste.
  2. Dies liegt daran, dass Schema (und Racket in diesem Fall) im Allgemeinen eine Sprache ist, die den funktionalen Stil bevorzugt.
  3. Sie könnten etwas näher mit set! kommen - aber selbst das wird Sie enttäuschen, da nur die lokale Bindung geändert wird.
  4. Beachten Sie, dass insbesondere in Racket Listen unveränderlich sind, also nichts , das eine Liste ändern kann.
  5. Selbst wenn Sie eine Liste auf diese Weise ändern könnten, ist dies eine sehr ineffiziente Möglichkeit, lange Listen zu sammeln, da Sie die gesamte Liste wiederholt scannen müssen.
  6. Wenn Sie Probleme auf dieser Ebene haben, empfehle ich Ihnen dringend, HtDP zu besuchen
Eli Barzilay 03.07.2010 20:29
quelle
2

(append foo bar) gibt die Verkettung von foo und bar zurück. Es ändert sich weder foo noch bar .

    
sepp2k 03.07.2010 20:25
quelle
0

Sie müssen den Wert von currVal mit set! aktualisieren. Ihr Beispiel sollte

haben %Vor%     
keithm 03.07.2010 20:26
quelle
0

Sie müssen wirklich darüber nachdenken, welche genaue Funktionalität Sie suchen

Wenn Sie eine referenzierte Liste an Ort und Stelle mutieren möchten, müssen Sie das Äquivalent von append ausführen! (wie in den anderen Antworten erwähnt). Aber das ist gefährlich, weil Sie möglicherweise anderen Code haben, der auf der Liste zählt, die unveränderlich ist, und wenn Sie das tun werden, muss Ihr Verfahren eine haben! am Ende, um diese Gefahr zu kennzeichnen.

Eine billige Annäherung an das, was Sie tun möchten, in einem funktionaleren Stil, ist:

%Vor%

Beachten Sie, dass es eine neue Liste erstellt, anfügt, das Ergebnis anzeigt und die neue Liste als Wert zurückgibt. Dies ist eine nützliche Debugging-Methode, wenn Sie keinen Zugriff auf den Zwischenwert haben: Binden Sie eine Variable, zeigen oder protokollieren Sie sie und geben Sie sie dann zurück.

    
Dak 16.07.2010 00:04
quelle

Tags und Links