我正在尝试选择 Lisp 作为我的新语言,但我在解决如何让函数的一部分作用于传递给它的列表的每个元素上时遇到了一些问题。
为了学习如何解决这个问题,我试图编写一个相当基本的除法形式,当列表的一个元素为 0 时不会发出声音(而是只返回 0)
(defun divtest (elements)
(dolist (x elements)
(if (zerop x) 0 () )
(/ elements)))))
我尝试将其运行为:
(divtest '(20 2 5))
其结果是:
*** - /: (20 2 5) is not a number
失败点似乎根源于这样一个事实:我在将列表中的元素传递给函数之前没有“提取”它们(在这种情况下, / 和 dolist 都没有按预期工作,因为 x 永远不会计算为 0)。
如果我是对的,有人可以告诉我如何进行这种“提取”吗?
注:此问题涉及我之前问过的一个 https://stackoverflow.com/questions/8937121/typesafe-and-arguement-safe-division-in-common-lisp,但由于我不清楚之前答案的哪一部分实际上允许它按预期解决这个特定问题,所以我决定进一步深入基础知识
/
接受一个或多个数字作为参数,但在你的代码中你传递给它一个列表 - 显然这是行不通的。功能apply
你的朋友在这里吗-(apply #'foo a b (list c d e))
相当于(foo a b c d e)
。请注意参数apply
要使用的函数和最终列表之间是可选的,所以(apply #'/ '(20 2 5))
相当于(/ 20 2 5)
.
此外,您尝试删除零将不起作用。dolist
正在评估参数列表中每个项目的主体elements
,但你实际上并没有做任何事情来改变内容elements
(评估结果dolist
s 主体没有像您预期的那样重新分配给源元素)。
功能remove-if
(及其破坏性的对应物,delete-if
)是您正在寻找的。下面展示了如何使用它(它需要很多可选参数,为此您无需担心)。
(defun divtest (elements)
(apply #'/ (remove-if #'zerop elements)))
另请注意,如果elements
列表的第一个元素为零(假设我理解该函数的含义)。所以你可能想要类似的东西
(defun divtest (elements)
(apply #'/ (first elements) (remove-if #'zerop (rest elements))))
有关更多详细信息,请参阅超规范。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)