Clojure中“recur”的正确用法?

Clojure中“recur”的正确用法?,clojure,tail-recursion,Clojure,Tail Recursion,我正在尝试解决上的问题,但我无法找出使用recur: fn [s] ( fn [t n] ( if (empty t) n (recur (rest t) (+ n 1)) ) s 0 ) 它给出了以下例外情况: java.lang.UnsupportedOperationException:只能从尾部位置重复,正在编译:(无源路径:0) 但对我来说,对recur的调用似乎是内部函数的尾部位置。我遗漏了什么?两个问

我正在尝试解决上的问题,但我无法找出使用
recur

fn [s] (
    fn [t n] (
        if (empty t)
            n
            (recur (rest t) (+ n 1))
    ) s 0
)
它给出了以下例外情况:

java.lang.UnsupportedOperationException:只能从尾部位置重复,正在编译:(无源路径:0)

但对我来说,对
recur
的调用似乎是内部函数的尾部位置。我遗漏了什么?

两个问题:

  • 你的括号放错地方了
  • 你在想用的地方用
括号

  • 用于定义函数的
    (fn name?[params*]exprs*)
    ,带括号
  • 另一级括号应用函数
    ((fn[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

两个问题:

  • 你的括号放错地方了
  • 你在想用的地方用
括号

  • 用于定义函数的
    (fn name?[params*]exprs*)
    ,带括号
  • 另一级括号应用函数
    ((fn[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

@缩略图是正确的——如果您确定了括号的位置,您的代码将正常工作(最重要的是,您需要在
之前添加一个
)(fn[t n]…
和相应的
s 0
之后,以便实际返回调用该函数的结果(将
t
n
作为参数的函数)对值
s
0
执行操作。否则,您将返回函数本身。),并将
empty
更改为
empty?

如果你想简化一些事情,你可以考虑使用<代码>循环<代码> >代码> ReCurr> <代码>结构,像这样:

(fn [s]
  (loop [t s, n 0]
    (if (empty? t)
      n
      (recur (rest t) (+ n 1)))))
@缩略图是正确的——如果您确定了括号的位置,您的代码将正常工作(最重要的是,您需要在
之前添加一个
)(fn[t n]…
和相应的
s 0
之后,以便实际返回调用该函数的结果(将
t
n
作为参数的函数)对值
s
0
执行操作。否则,您将返回函数本身。),并将
empty
更改为
empty?

如果你想简化一些事情,你可以考虑使用<代码>循环<代码> >代码> ReCurr> <代码>结构,像这样:

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

嗯,谢谢。移动括号会对代码的含义产生影响吗?还是仅仅是可读性?将
更改为
空?
并不能解决这一问题……我将读取
defn
fn
之间的差异,尽管
defn
在4clojure解决方案中是不允许的。@Armand移动括号会改变代码的结构因此改变了它的含义。我使用了
defn
而不是
fn
来区分函数的定义和使用。只需将其更改回去,如果您愿意,请删除名称
l
。我想我是想说您的代码基本上是正确的,除了毫无意义:).aha!我以为你反对缩进,但实际上你的意思是我缺少一组括号(我想!):-)现在起作用了,我觉得有点傻-谢谢谢谢。移动括号会对代码的含义产生影响吗,还是仅仅是可读性?将
empty
更改为
empty?
并不能解决这个问题……我会读出
defn
fn
之间的区别,尽管
defn
在4clojur中是不允许的e解决方案。@Armand移动括号改变了代码的结构,从而改变了它的含义。我用
defn
而不是
fn
来区分函数的定义和用法。只要把它改回去,如果你愿意的话,去掉名称
l
。我想说你的代码基本上是正确的,除了胡说八道之外:).aha!我以为你反对缩进,但实际上你的意思是我缺少了一组括号(我想!):-)现在可以工作了,我觉得有点愚蠢-感谢任务没有说明应该使用
recur
,虽然知道这一点很好,它也被认为是较低级别的构建块。有一些高级函数,您可以使用这些函数以更具可读性和习惯性的方式来解决此问题。任务没有说明应该使用
recurr
,虽然了解它很好,但它也被认为是较低级别的构建块。有一些高级函数,您可以使用它们以更具可读性和习惯性的方式解决此问题。