Frage

Ich lerne R5RS Schema zur Zeit (von PocketScheme) und ich finde, dass ich eine Funktion nutzen könnten, die in einigen Varianten von Schema aufgebaut ist, aber nicht alle: anhängen

Mit anderen Worten -. Destruktiv eine Liste zu ändern

Ich bin nicht so sehr interessiert in dem eigentlichen Code als Antwort so viel wie den Prozess zu verstehen, mit denen man eine Liste als eine Funktion übergeben konnte (oder einen Vektor oder string) und mutiert es dann.

Beispiel:

(define (append! lst var)
    (cons (lst var))
)

Wenn ich den Ansatz verwenden, wie oben, ich habe so etwas wie (define list (append! foo (bar)) zu tun, was ich etwas allgemeinere möchte.

War es hilfreich?

Lösung

Mutation, obwohl erlaubt, ist stark in Schema abgeraten. PLT ging sogar so weit, set-car! und set-cdr! zu entfernen (obwohl sie „ersetzt“, um sie mit set-mcar! und set-mcdr!). Allerdings schien eine Spezifikation für append! in SRFI-1 . Diese append! ist ein wenig anders als deine. Im SRFI, die Umsetzung können , ist aber nicht erforderlich die Nachteile Zellen zu modifizieren, um die Listen anzuhängen.

Wenn Sie eine append! haben wollen, das ist garantiert die Struktur der Liste zu ändern, die angehängt ist wird, werden Sie wahrscheinlich selbst, es zu schreiben. Es ist nicht schwer:

(define (my-append! a b)
  (if (null? (cdr a))
      (set-cdr! a b)
      (my-append! (cdr a) b)))

Um die Definition einfach zu halten, gibt es keine Fehlerprüfung hier, aber es ist klar, dass Sie in einer Liste der Länge mindestens 1 als a passieren müssen, und (vorzugsweise) eine Liste (beliebige Länge) als b. Der Grund a muss mindestens Länge 1 ist, weil Sie nicht auf eine leere Liste set-cdr! kann.

Da Sie sind daran interessiert, wie das funktioniert, werde ich sehen, ob ich erklären kann. Im Grunde, was wir tun wollen ist die Liste a geht nach unten, bis wir zum letzten cons Paar bekommen, die (<last element> . null) ist. So sehen wir zum ersten Mal, wenn a ist bereits das letzte Element in der Liste von in den null für cdr überprüfen. Wenn es ist, verwenden set-cdr! wir es auf die Liste setzen wir anhängen, und wir sind fertig. Wenn nicht, haben wir my-append! auf der cdr von a zu nennen. Jedes Mal, wenn wir dies tun wir näher am Ende a. Da dies eine Mutations-Operation ist, sind wir nichts geht zurück, so müssen wir nicht über Bildung unserer modifizierten Liste als Rückgabewert sorgen.

Andere Tipps

Besser spät als nie in ein paar Putting 2-3 Cent zu diesem Thema ...

(1) Es ist nichts falsch mit den destruktiven Verfahren in Schema mit , während gibt es einen einzigen Verweis auf die stucture modifizierte. So zum Beispiel, den Aufbau einer großen Liste effizient, Stück für Stück über eine einzige Referenz - und wenn Sie fertig sind, dass zu machen (jetzt vermutlich nicht-zu-sein-modifizierte) Liste bekannt und indirekten Verweisen auf verschiedenen referents

.

(2) Ich denke, APPEND! sollte wie APPEND verhalten, nur (potentiell) destruktiv. Und so APPEND! erwartet eine beliebige Anzahl von Listen als Argumente sollte. Jede Liste, aber der letzte wäre vermutlich SET-CDR werden! 'D zum nächsten.

(3) Die obige Definition von APPEND! im Wesentlichen ist NCONC von Mac Lisp und Common Lisp. (Und andere lispelt).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top