【发布时间】:2011-07-08 12:32:39
【问题描述】:
Clojure 中 Lisp 的 caddr 等价物是什么?
【问题讨论】:
Clojure 中 Lisp 的 caddr 等价物是什么?
【问题讨论】:
Lisps 中的 caddr 经常以相当于解构的方式使用。 Clojure 普遍支持解构,因此 caddr 用处不大。
(let [[_ _ x] [1 2 3 4]]
x) ;; -> 3
编辑:回应@4bu3li。
(defn describe-path [[first :as edge]]
`(there is a ~(last edge) going ~first from here.))
没有办法指定最后一个带有解构的元素,但这与原始问题并没有真正的关系。
【讨论】:
[1 2],则x 将为零,因为没有第三项。
通常当我需要将概念从一种语言映射到另一种语言时,我会检查http://hyperpolyglot.org/
Clojure 包含在 Lisp 页面中:http://hyperpolyglot.org/lisp
由此看来,与caddr没有直接的相似之处。
【讨论】:
我想(caddr foo) 最接近的等价物是(first (nnext foo))。但是 Clojure 并不完全具有大多数 Lisp 所拥有的“一切都是列表”的信仰,并且缺少 Common Lisp 中支持序列共享接口的大量列表遍历快捷方式。
【讨论】:
编写和制作自己的 ca+d+r 函数并不难
(defn make-cadr
[fn-name]
(let [cadr {\a first \d rest}]
(apply comp (map cadr (butlast (drop 1 fn-name))))))
((make-cadr "caddr") [1 2 3 4 5])
【讨论】:
Clojure 中没有与 caddr 等效的direct,因为 Clojure 处理的是序列而不是具体的 cons 单元格。值得一读的是Clojure documentation on sequences。
【讨论】:
你可以这样做:
(defn caddr [list]
(first (rest (rest list))))
【讨论】:
与 Sathish 的回答略有不同,但使用了编译 cadr 函数的宏:
(defmacro cadr-compiler [name]
(let [cadr {\a first \d rest}]
`(defn ~name [l#]
((apply comp (map ~cadr (butlast (drop 1 ~(str name))))) l#))))
(cadr-compiler caddr)
(caddr [1 2 3 4 5]) ;=> 3
【讨论】: