欲瞭解更多有關如何實現flatten
(這是這種功能通常被稱爲),看看
至於您的特定錯誤, append
預計其所有參數(通常可能需要兩個以上)是列表。例如,
> (append '(1 2 3) '(4 5 6))
;=> (1 2 3 4 5 6)
> (append '(1 2 3) '(4 5 6) '(7 8 9))
;=> (1 2 3 4 5 6 7 8 9)
現在,你寫你的函數,和你說level
應該返回一個列表。這意味着如果level
有幾個不同的執行路徑,每個需要產生一個列表。所以,讓我們來看看你的實現。
(define level
(lambda (L)
(cond ((null? L) L)
((not(pair? L)) L)
(else (append (level(car L)) (level(cdr L)))))))
在的問題,你說你寫的應該採取列表的功能,所以L
可以是兩件事情之一;它可以是空列表,也可以是一對。目前,您的cond
有三個個案,但。
(cond ((null? L) L) ; handle an empty list
((not(pair? L)) L)
(else (append (level(car L)) (level(cdr L))))) ; handle a pair
如果你總是用列表調用level
,你並不需要的第二種情況。然而,由於在第三種情況下,你做呼叫(level (car L))
,你不知道要不要(car L)
是否將是一個列表,好像你做最終調用level
與非名單。您需要決定是否合適,例如(level 'a)
是否合法,以及是否應該合法。目前,您似乎想要使(level 'a)
合法,並返回(a)
。這很好,但你應該指定合同。如果這是你想要做的,那麼你確實需要第二種情況在你的cond
,但因爲(level 'a)
應該返回(a)
,你實際上需要這種情況下返回(list L)
,而不是L
。
這裏的另一種選擇,如果你做想level
要嚴格,並總是需要一個列表作爲參數,那麼你需要添加一些邏輯來確定(car L)
是否是一個列表,如果是,遞歸調用level
,並調用append
的結果。這樣做的一個方法是這樣的:
(define (level L)
(cond
((null? L) L)
((pair? L) (append (if (list? (car L))
(level (car L))
(list L))
(level (cdr L))))))