lisp - 让里面条件

标签 lisp clojure

我正在使用 clojure,虽然我之前曾涉足过 lisp,但我很难找到一种干净的方法来将 let 语句嵌套在 cond 语句中。例如,考虑以下函数:

(defn operate-on-list [xs]
  (let [[unpack vector] (first xs)]
    (cond
      [(empty? xs) 'empty
       unpack vector
       :else (operate-on-list (rest xs))])))

这是一个非常标准的列表递归操作,但它需要在处理列表的第一个元素之前对列表中的第一个元素做一些处理。当然,问题是列表可能是空的。

在这个例子中,不难改变unpack((first xs) 0)vector((first xs) 1) , 但如果需要在 (first xs) 上完成更多工作,这很快就会变得丑陋。

有什么方法可以有效地在 cond 中使用 let 语句?

谢谢。

-内特

最佳答案

在这种情况下,您最好使用 if-let:

(defn operate-on-list [xs]
  (if-let [[unpack v] (first xs)]
    (cond
      unpack v
      :else  (operate-on-list (rest xs)))))

此代码遍历给定的list seq-able(列表、向量、数组...)向量并返回第一个元素为真的第一个向量的第二个元素(意思不是falsenil)。如果找不到这样的向量,则返回 nil

注意 vector 是一个内置函数,所以我选择了 v 作为变量名,以防需要在主体中使用该函数将来出现。更重要的是,您在 cond 语法中使用了太多括号;在此版本中已修复。

更新:关于 if-let 还有两点值得注意:

  1. if-let 的工作方式,如果 (first xs) 恰好是 nil (false 将是相同的),解构绑定(bind)永远不会发生,因此 Clojure 不会提示无法将 nil 绑定(bind)到 [unpack v]

  2. 此外,if-let 接受一个 else 子句(您不能在其中引用 if-let 绑定(bind)向量中绑定(bind)的变量——尽管如果你在 else 子句中,你知道它们在哪里 falsenil

关于lisp - 让里面条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2067832/

相关文章:

lisp - 如何查看 lisp (sbcl) 中函数的定义?

Clojure 对比其他 Lisp

java - 从 jdbc (clojure/java) 生成 "create table"脚本

clojure - 为什么这个部分不起作用

clojure - 高效序列化 : spit, with-out-str, pr

lisp - 如何在多个读取行中进行自动输入?

scheme - 模块中的未绑定(bind)标识符 - DrRacket

clojure - 如何使用 n-arg 谓词过滤 n-元组的 seq?

concurrency - 了解 Clojure 并发示例

macros - 方案;宏列表中的错误漏洞