我想将定义的函数转换为匿名函数。我怎么做?以下函数返回序列中的最后一个元素:
(defn lastt [l]
(cond
(nil? (next l)) l
:else
(lastt (next l))))
如何将其转换为fn
表单?
PS:我知道last
功能,这只是一个练习。
答案 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
递归以来,您需要提供一个名称以将其绑定到正文中。