Sie bearbeiten die ursprüngliche Frage mit aktualisiertem Code haben, die macht es zu einem beweglichen Ziel. Derzeit ist der Code das folgende, nachdem ich Emacs fragen sie einrücken mit Mq (Lisp-Modus):
(defun flatten (list)
(cond
((null list)t)
(list (first list) (rest list))
(t (append (flatten (first list))
(flatten (rest list)))
(t (cons (first list (flatten (rest list))))))))
;; ^^^ Something is not good, why is the clause indented?
Klammerung Struktur der Code für den Computer, während Vertiefung ist ein Weg, um diese Struktur zu drucken für menschliche Leser. Diese Redundanz ermöglicht es Ihnen, Probleme im Quellcode zu erkennen, wenn einer nicht mit dem anderen übereinstimmt. Hier ist die (t cons)
keine Cond-Klausel, sie ist in der vorherigen Klausel verschachtelt.
Zweitens, wie in den Kommentaren gesagt, cond
wird zu der ersten Klausel gehen, für die der Test erfolgreich ist. Wenn Sie (cond (t X) ...)
schreiben, würde nichts in dem ...
Teil die Bedeutung des Codes ändern, der immer X
zurückgibt. In Ihrem Code, testen Sie wie folgt vor:
(null list)
prüft, ob list
eq
-nil
ist.
list
nicht testen, ob list
eine Liste ist. Es gibt ein Prädikat namens listp
, das zu erkennen. Wenn Sie list
so eingeben, fragen Sie, ob list
ein verallgemeinerter wahrer Wert ist, der notwendigerweise wahr ist, wenn Sie zuvor nil
ausschlossen (die vorherige Klausel).
- Die Standardklausel
(t ...)
kann nicht verwendet werden, da der vorherige Test nicht fehlschlagen kann. Hier
ist ein Skelett:
(defun flatten (form)
(cond
((null list) ...)
((consp list) ...)
(t ...)))
Statt consp
Sie listp
schreiben konnte, aber beachten Sie, dass per Definition eine Liste entweder nil
oder eine cons Zelle, so consp
ist ein wenig expliziter und tut Überschneidung mit einem Test für nil
nicht. Beachten Sie auch, dass ich immer gegen den Typ der Form teste, der ein Muster ist, das oft gefunden wird. Deshalb möchten Sie vielleicht typecase
verwenden.
'(Liste (erste Liste))' - weil Sie es sagen, nur das erste Element zurückgeben? – melpomene
@melpomene Ich habe gerade realisiert, was ich getan habe, danke für die Klarstellung –
Jetzt sagt dein Code: Wenn '(Nullliste)' (d. H. Wenn 'Liste' leer ist/nil), gib 't' zurück. Andernfalls, wenn "list" (d. H. Wenn list nicht-leer ist/nicht nil), hole das erste Element und ignoriere es, dann hole den "Rest" (alles außer dem ersten Element) und gebe das zurück. Ihr verbleibender Code ist irrelevant, weil eine der beiden ersten Bedingungen immer wahr ist. – melpomene