Recursion 使用默认可选参数并在Clojure中一起重复
我可以设置默认参数并使用它执行常规递归,但由于某些原因,我无法使用RecurforTail优化。。。我一直得到一个java.lang.UnsupportedOperationException:nth不支持此类型:Long错误 例如,对于尾部调用阶乘,以下是有效的,但不是针对尾部调用递归优化的,并且对于大型递归堆栈将失败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
(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编译器的源代码以及编译的类