gpt4 book ai didi

list - 为什么我的 lisp 函数给我这个输出?

转载 作者:太空宇宙 更新时间:2023-11-03 19:03:02 28 4
gpt4 key购买 nike

我正在编写一个函数,它将从用户那里获取一个列表,并将该列表展平为一个简化的列表。该函数似乎只返回列表中的第一项而不返回其余项?关于为什么这样做有什么建议吗?

例子:

> (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 使用 M-q (lisp-mode) 缩进它之后:

(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是否为eq to nil
  2. list 测试list是否是一个列表。有一个名为 listp 的谓词来检测它。当您像这样单独放置 list 时,您是在询问 list 是否是一个广义真值,当您之前排除了 nil 时,这必然为真(前一条)。
  3. 默认子句(t ...) 没有办法使用,因为前面的测试不可能失败。

这是一个骨架:

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

您可以编写 listp 而不是 consp,但请注意,根据定义,列表要么是 nil 要么是 cons 单元格,因此 consp 更明确一点,不会与 nil 的测试重叠。另请注意,我总是针对表单类型进行测试,这是一种经常发现的模式。这就是为什么您可能更喜欢使用 typecase 的原因.

关于list - 为什么我的 lisp 函数给我这个输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42322460/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com