2012-05-26 72 views
2

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

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

如何将它转换为fn表单?

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

+0

你还是要定义一个函数,或者你只是想一个匿名函数? – outis

+0

@outis anonymous –

+1

请用所需信息更新问题。一般而言,通过更新您的帖子来回应澄清请求,而不是回复评论。首先,如果没有阅读评论,一个问题应该是可以理解的。另一方面,SO是Q&A网站,而不是论坛,评论意图不适合(也不适合)讨论。 – outis

回答

8

首先,该函数返回一个列表中的最后一个列表。我会改变你的定义,使其返回只是的最后一个项目:

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

为了简化,我会使用一个let结合,因为你在l调用next两次:

(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

+1使用反复和解构:) – ivant

+0

谢谢,几乎觉得我知道我现在正在做一半的时间。 :) –

+1

你可以在这里使用if而不是'cond',并且使用'fn'而不是'#'可以直接在args中进行解构:'(fn [[h&t]](if(空?t)h(recur t)))' – ivant

6

我更奸人的/德克勒比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递归,您需要提供一个名称将其绑定到正文中。

+0

对于defn你是对的。这是一个宏观。 – octopusgrabbus

相关问题