在Clojure中正确使用`recur`?

时间:2014-06-04 08:54:58

标签: clojure tail-recursion

我试图解决Count a Sequence上的4Clojure问题,但我无法解决使用recur时出现的问题:

fn [s] (
    fn [t n] (
        if (empty t)
            n
            (recur (rest t) (+ n 1))
    ) s 0
)

它提供以下例外:

  

java.lang.UnsupportedOperationException:只能从尾部位置重现,编译:(NO_SOURCE_PATH:0)

但对我而言,似乎recur 的调用是在内部函数的尾部位置。我错过了什么?

2 个答案:

答案 0 :(得分:3)

两个问题:

括号

  • 用于定义函数的{{3}}采用该形状 (fn name? [params* ] exprs*)周围有括号。
  • 另一级括号应用函数((fn [n] (* n n)) 3) => 9

目前使用defn代替fn,我们得到

(defn l [s] 
  ((fn [t n] (if (empty? t) n (recur (rest t) (+ n 1))))
       s 0))

然后,例如,

(l ())
; 0

(l [1 2 3])
; 3

答案 1 :(得分:3)

@Thumbnail是正确的 - 如果您修复括号的位置,您的代码就可以正常工作(最重要的是,您需要在(之前添加(fn [t n] ...以及相应的{{1}在)之后,为了在值s 0和{{1}上实际返回调用该函数的结果(将tn作为参数的结果)否则,您将返回函数本身。),并将s更改为0

如果您想稍微简化一下,可以考虑使用empty / empty?结构,如下所示:

loop