如何将已定义的函数函数转换为匿名函数

时间:2012-05-26 06:27:07

标签: clojure

我想将定义的函数转换为匿名函数。我怎么做?以下函数返回序列中的最后一个元素:

(defn lastt [l]
    (cond
        (nil? (next l)) l
        :else
            (lastt (next l))))

如何将其转换为fn表单?

PS:我知道last功能,这只是一个练习。

2 个答案:

答案 0 :(得分:7)

首先,该函数返回一个包含最后一项的列表。我会更改您的定义,以便返回 最后一项:

(defn lastt [l]
  (cond
   (nil? (next l)) (first l)
   :else (lastt (next l))))

为了简化,我使用了let绑定,因为您在next上拨打l两次:

(defn lastt [l]
  (let [n (next l)]
    (cond
     (nil? n) (first l)
     :else (lastt n))))

我接下来要做的就是将最后一次调用替换为lastt以使用recur代替

(defn lastt [l]
  (let [n (next l)]
    (cond
     (nil? n) (first l)
     :else (recur n))))

然后我用

替换它
#(let [n (next %)]
   (cond
    (nil? n) (first %)
    :else (recur n)))

只是意识到使用解构可以简化它:)

#(let [[h & t] %]
   (cond
    (nil? t) h
    :else (recur t)))

<强>更新

不需要cond,因为只有两个分支,并且使用fn代替#简写将允许在fn中进行解构参数,使整个功能更简洁:

(fn [[h & t]]
  (if (empty? t) h
      (recur t)))

答案 1 :(得分:6)

我更像是一个策划者/ CLer而不是一个clojer,但(defn f [args] body)看起来主要是(def f (fn f ([args] body)))的语法糖,在这种情况下lastt可以写成匿名函数省略def

(fn lastt 
    ([l] (cond
           (nil? (next l))
             l
           :else
             (lastt (next l)))))

lastt递归以来,您需要提供一个名称以将其绑定到正文中。