2016-04-06 1 views
0

Versuchen, Funktionen höherer Ordnung in Schema zu verstehen, und ich habe eine harte Zeit versucht, eine Liste mit diesen Funktionen zu glätten. (Abflachen '(a (b) (c))) -> (abc)Schema flachte eine Liste mit nur cond, atom ?, null ?, map, append und foldl/foldr

(define (flatten s) 
     (cond ((null? s) '()) 
      (foldr (lambda(x) (if (atom? x) (append x) 
          (list x))) s '()))) 

(abflachen' (a (b) c)) liefert ‚()

Ich bin nicht sicher, wie map hier zu verwenden und wie kann ich das mit foldl machen? Danke

+0

Wollen Sie das Atom von 'HTDP/docs' oder einem anderen? – Majora320

+0

danke, mit cond auf diese Weise war ein dummer Fehler. – user3128077

Antwort

0

Sie verwenden cond falsch. Der Auftrag der besonderen Form ist:

(cond 
    (predicate consequent1 consequent2 ...) ...) 

Das letzte Prädikat das Symbol else sein kann. Betrachten Sie cond das ist, wie es interpretiert hat:

(cond ((null? s)  ; predicate 
     '())    ; consequent1 (result) 
     (foldr   ; predicate (always true since only #f is false) 
     (lambda (x)  ; consequent1 (dead code) 
     (if (atom? x) 
      (append x) 
      (list x))) 
     s    ; consequent2 (dead code) 
     '())))   ; consequent3 (result) 

Wie Sie sehen es die Klammern um den letzten Term fehlt foldr das Prädikat zu machen. Auch mit den Klammern fehlt es else als Prädikat und ohne es fold wird nur verwendet, um zu überprüfen, ob es nicht #f ist und nicht als die tatsächliche Folge.

Da beide Begriffe zu () evalutes und das letzte Prädikat ist immer wahr () wäre das Ergebnis die ganze Zeit.

Mit foldl würden Sie die Elemente in umgekehrter Reihenfolge erhalten, aber es wäre schneller. Mit foldr können Sie es wie folgt tun:

(define (flatten lst) 
    (let helper ((lst lst) (acc '())) 
    (foldr (lambda (e acc) 
      (cond ((null? e) acc) 
        ((pair? e) (helper e acc)) 
        (else (cons e acc)))) 
      acc 
      lst)))