Цель состоит в том, чтобы устранить все внутренние скобки.
(сгладить (a (bc) d)) становится '(abcd)
Это мой код в Racket
; if slist is null, return empty
; otherwise, if it is a pair, recursively solve car and cdr and concat them
; if it is a symbol, return the symbol
(define flatten
(lambda (slist)
(cond
[ (null? slist) '()]
[ (pair? slist)
(cons ((flatten (car slist)) (flatten (cdr slist))))]
[ (symbol? slist) slist])))
Этожаловаться
procedure application: expected procedure, given: c; arguments were: ()
, что означает, что я пытаюсь получить доступ к car
и cdr
из пустого списка.
I did the trace:
> (flatten '(a (b c) d))
pair?-car-cdr
a
((b c) d)
symbol?
a
pair?-car-cdr
(b c)
(d)
pair?-car-cdr
b
(c)
symbol?
b
pair?-car-cdr
c
()
symbol?
c
(stops here)
Код трассировки прост - несколько дисплеев.
(define flatten
(lambda (slist)
(cond
[ (null? slist) '()]
[ (pair? slist)
(display 'pair?-car-cdr)
(newline)
(display (car slist))
(newline)
(display (cdr slist))
(newline)
(cons ((flatten (car slist)) (flatten (cdr slist))))]
[ (symbol? slist)
(display 'symbol?)
(newline)
(display slist)
(newline)
slist])))
Я не понимаю, почему первое условие (null? slist)
не перехватило пустой список?У меня есть два рекурсивных вызова.Если он перехватит пустой список, он перейдет к следующей рекурсии, которая является списком {d}
.
В чем проблема с моей логикой рекурсии?
Обновить версию
(define flatten
(lambda (slist)
(cond
[ (null? slist) '()]
[ (pair? slist)
(cons (flatten (car slist)) (flatten (cdr slist)))]
[ (symbol? slist) slist])))
(display (equal? (flatten '(a (b a) b a c (a b) c (e f (b a)))) '(a b a b a c a b c e f b a)))
(newline)
(display (equal? (flatten '(a b c)) '(a b c)))
(newline)
(display (equal? (flatten '(a (b c))) '(a b c)))
(newline)
(display (equal? (flatten '((a)(b)(c) d)) '(a b c d)))
(newline)
(display (equal? (flatten '(a (b) ((c)) (((d))) ((((e (f g))))))) '(a b c d e f g )))
(newline)
(display (equal? (flatten '()) '()))
(newline)
(display (equal? (flatten '(a b () ())) '(a b)))
(newline)
Как предположил Росс Ларсон, append заставит программу работать.Но ради изучения, если у кого-то есть время, чтобы сэкономить, результаты моих тестов показывают только пройденные базовые случаи (2-й и пустой список)
Я думал о написании функции-оболочки, которая вызывает (cons (flatten slist) empty)