Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion 使用默认可选参数并在Clojure中一起重复_Recursion_Clojure_Tail Call Optimization - Fatal编程技术网

Recursion 使用默认可选参数并在Clojure中一起重复

Recursion 使用默认可选参数并在Clojure中一起重复,recursion,clojure,tail-call-optimization,Recursion,Clojure,Tail Call Optimization,我可以设置默认参数并使用它执行常规递归,但由于某些原因,我无法使用RecurforTail优化。。。我一直得到一个java.lang.UnsupportedOperationException:nth不支持此类型:Long错误 例如,对于尾部调用阶乘,以下是有效的,但不是针对尾部调用递归优化的,并且对于大型递归堆栈将失败 (defn foo [n & [optional]] (if (= n 0) (or optional 1) (foo (dec n) (*' (or op

我可以设置默认参数并使用它执行常规递归,但由于某些原因,我无法使用RecurforTail优化。。。我一直得到一个java.lang.UnsupportedOperationException:nth不支持此类型:Long错误

例如,对于尾部调用阶乘,以下是有效的,但不是针对尾部调用递归优化的,并且对于大型递归堆栈将失败

(defn foo [n & [optional]]
   (if (= n 0) (or optional 1)
   (foo (dec n) (*' (or optional 1) n))))
我称之为foo3

当我尝试获取TCO时,我得到了不受支持的操作错误

(defn foo [n & [optional]]
   (if (= n 0) (or optional 1)
   (recur (dec n) (*' (or optional 1) n))))
我把这个叫做foo 3

为什么这种差异会导致错误?我怎样才能使用可选的默认参数进行TCO

谢谢大家!

编辑:

当我试图在递归调用中去掉or可选1并使其成为可选时,我得到一个空异常错误。。。这是有道理的

当我试图删除递归调用中的“from*”时,这也没有得到解决


编辑:我也更喜欢在没有循环的情况下执行此操作

您可以为函数提供多个不同的算术运算。这可能就是你想要的

(defn foo
  ([n]
    (foo n 1))
  ([n optional]
   (if (= n 0)
     (or optional 1)
     (recur (dec n) (*' (or optional 1) n)))))
我不太明白为什么会出现错误,但recur通常不会用于具有可选参数的函数中

编辑:在阅读了其他答案链接后,我现在明白了。recur不会像调用函数时那样分解rest参数。如果使用集合作为第二个参数重复出现,它将起作用,但最好使用两个不同的算术表达式来显式显示:

(defn foo [n & [optional]]
  (if (= n 0)
    (or optional 1)
    (recur (dec n) [(*' (or optional 1) n)])))

你可以给一个函数多个不同的算术。这可能就是你想要的

(defn foo
  ([n]
    (foo n 1))
  ([n optional]
   (if (= n 0)
     (or optional 1)
     (recur (dec n) (*' (or optional 1) n)))))
我不太明白为什么会出现错误,但recur通常不会用于具有可选参数的函数中

编辑:在阅读了其他答案链接后,我现在明白了。recur不会像调用函数时那样分解rest参数。如果使用集合作为第二个参数重复出现,它将起作用,但最好使用两个不同的算术表达式来显式显示:

(defn foo [n & [optional]]
  (if (= n 0)
    (or optional 1)
    (recur (dec n) [(*' (or optional 1) n)])))
为什么这种差异会导致错误

简言之,它试图分解一个长的,但它不能 直呼 接受n个参数 自动将第一个参数n之后的所有内容放在幕后的seq中,可以对其进行分解 重复呼叫foo 只接受2个参数 第一个参数:n 第二个参数:与其余参数相匹配的内容 我怎样才能使用可选的默认参数进行TCO

只需将第二个参数换行如下: 建议 尽管他没有回答你的问题,@DanielCompton的建议是以更清晰、更有效的方式从一开始就完全避免这个问题的方法 为什么这种差异会导致错误

简言之,它试图分解一个长的,但它不能 直呼 接受n个参数 自动将第一个参数n之后的所有内容放在幕后的seq中,可以对其进行分解 重复呼叫foo 只接受2个参数 第一个参数:n 第二个参数:与其余参数相匹配的内容 我怎样才能使用可选的默认参数进行TCO

只需将第二个参数换行如下: 建议 尽管他没有回答你的问题,@DanielCompton的建议是以更清晰、更有效的方式从一开始就完全避免这个问题的方法 它是:

Recur不会重新进入函数,它只是返回到顶部,vararging不会再次发生。。。再次收集,你会没事的

我个人认为它应该在RecurDocstring中提及,或者至少出现在doc中。需要一点挖掘才能理解发生了什么,我必须检查Clojure编译器源代码以及编译的类。

它是:

Recur不会重新进入函数,它只是返回到顶部,vararging不会再次发生。。。再次收集,你会没事的

我个人认为它应该在RecurDocstring中提及,或者至少出现在doc中。需要一点挖掘来理解发生了什么,我必须检查Clojure编译器的源代码以及编译的类