簡體   English   中英

為什么我的lisp函數給我這個輸出?

[英]Why is my lisp function giving me this output?

我正在編寫一個函數,該函數將從用戶的列表中提取一個列表並將其平整為一個簡化的列表。 該函數似乎僅返回列表中的第一項,而不返回其余項? 關於為什么要這樣做的任何建議?

例:

> (flatten '(a () b (c d))
(a b c d)

這就是我到目前為止

(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))))))))

它給出的輸出

> (flatten '(a () b (c d)))
(NIL B (C D))

您正在使用更新的代碼來編輯原始問題,這使其成為可移動的目標。 當前,在我要求Emacs使用Mq (lisp模式)將其縮進之后,您的代碼是以下代碼:

(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?  

括號是計算機代碼的結構,而縮進是一種為人類讀者打印這種結構的方法。 當一個不匹配時,這種冗余允許您檢測源代碼中的問題。 在這里, (t cons)不是cond子句,它嵌套在上一個子句中。

第二,如評論中所述, cond將轉到測試成功的第一個子句。 如果您編寫了(cond (t X) ...) ,則...部分中的任何內容都不會更改代碼的含義,該代碼始終返回X 在您的代碼中,您進行如下測試:

  1. (null list)測試list是否eqnil
  2. list 不會測試list是否為列表。 有一個名為listp的謂詞可以檢測到該謂詞。 當您像這樣單獨list時,您要詢問list是否是一個廣義的true值,當您先前排除nil (上一個子句)時,這一定是true。
  3. 不能使用默認子句(t ...) ,因為先前的測試不會失敗。

這是一個骨架:

(defun flatten (form)
  (cond
    ((null list) ...)
    ((consp list) ...)
    (t ...)))

您可以編寫listp代替consp ,但是請注意,根據定義,列表可以是nil或cons單元格,因此consp更加明確,並且與nil的測試不重疊。 還請注意,我總是針對表單的類型進行測試,這是一種經常發現的模式。 這就是為什么您可能更喜歡使用typecase

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM