【问题标题】:caddr in ClojureClojure 中的 caddr
【发布时间】:2011-07-08 12:32:39
【问题描述】:

Clojure 中 Lisp 的 caddr 等价物是什么?

【问题讨论】:

    标签: clojure lisp jvm


    【解决方案1】:

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

    没有办法指定最后一个带有解构的元素,但这与原始问题并没有真正的关系。

    【讨论】:

    • @Hamish Grubijian:好吧,任何 seq 的元素至少与绑定列表中的元素一样多。如果序列改为[1 2],则x 将为零,因为没有第三项。
    • @dnolan 使用这个函数可以进行破坏吗? (defn describe-path [edge] `(有一个 ~(last edge) 从这里到 ~(first edge)。))
    【解决方案2】:

    由于caddr 相当于Common Lisp 中的third,我在Clojure 中看到的最接近的是nth

    (nth collection 2)
    

    它比caddr 更通用,因为它渴望研究更多包含细胞链的结构。但请注意,它不是 Common Lisp 中的 place

    【讨论】:

    • 我想你的意思是(nth collection 2)——firstsecond 等函数从 1 开始,但 nth 从 0 开始。
    【解决方案3】:

    通常当我需要将概念从一种语言映射到另一种语言时,我会检查http://hyperpolyglot.org/

    Clojure 包含在 Lisp 页面中:http://hyperpolyglot.org/lisp

    由此看来,与caddr没有直接的相似之处。

    【讨论】:

      【解决方案4】:

      我想(caddr foo) 最接近的等价物是(first (nnext foo))。但是 Clojure 并不完全具有大多数 Lisp 所拥有的“一切都是列表”的信仰,并且缺少 Common Lisp 中支持序列共享接口的大量列表遍历快捷方式。

      【讨论】:

        【解决方案5】:

        编写和制作自己的 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]) 
        

        【讨论】:

        • +1 用于编译函数名称,我第一次看到这种技术 :-)
        【解决方案6】:

        Clojure 中没有与 caddr 等效的direct,因为 Clojure 处理的是序列而不是具体的 cons 单元格。值得一读的是Clojure documentation on sequences

        【讨论】:

          【解决方案7】:

          你可以这样做:

          (defn caddr [list]
            (first (rest (rest list))))
          

          【讨论】:

            【解决方案8】:

            与 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
            

            【讨论】:

              猜你喜欢
              • 2011-09-08
              • 1970-01-01
              • 1970-01-01
              • 2015-11-16
              • 1970-01-01
              • 1970-01-01
              • 2016-12-28
              • 2016-02-26
              • 2014-01-04
              相关资源
              最近更新 更多