我可以设置默认参数并使用它进行常规递归,但由于某些原因,我不能使用recur进行尾部优化……我一直收到一个java.lang.UnsupportedOperationException: nth not supported on this type: Long错误。
例如,对于尾部调用Factorial,以下是有效的方法,但没有针对尾部调用递归进行优化,并且对于大型递归堆栈将失败。
(defn foo [n & [optional]]
(if (= n 0) (or optional 1)
(foo (dec n) (*' (or optional 1) n))))我把这个叫做(foo 3)
当我尝试这样做以获得TCO时,我得到了不受支持的操作错误...
(defn foo [n & [optional]]
(if (= n 0) (or optional 1)
(recur (dec n) (*' (or optional 1) n))))我用同样的方式叫它(foo 3)
为什么这种差异会导致错误?我究竟如何使用可选的默认参数来实现总拥有成本?
谢谢!
编辑:
当我试图在递归调用中取出(or optional 1)并将其设为optional时,我得到了一个空异常错误...这是有道理的。
当我试图在递归调用中从*'中删除'时,这个问题也不会得到解决
编辑:我也更喜欢在没有loop的情况下这样做
发布于 2016-09-30 11:26:24
它是a known issue
递归不会重新进入函数,它只是返回到顶部(变数不会再次发生)……重复使用一个集合,你就会很好。
我个人认为它要么应该在recur文档字符串中提到,要么至少应该出现在文档中。需要一些挖掘才能理解发生了什么(我必须检查Clojure编译器源代码以及编译后的类)。
发布于 2016-09-30 10:50:19
你可以给一个函数赋予多个不同的特性。这可能是你要找的东西?
(defn foo
([n]
(foo n 1))
([n optional]
(if (= n 0)
(or optional 1)
(recur (dec n) (*' (or optional 1) n)))))我不太理解为什么会有错误,但是recur通常不会用在带有可选参数的函数中。
编辑:在阅读了其他答案链接后,我现在了解了problem。recur不会像调用函数时那样对rest参数进行解构。如果你重复使用一个集合作为第二个arg,它会起作用,但是用两个不同的符号来显式可能会更好:
(defn foo [n & [optional]]
(if (= n 0)
(or optional 1)
(recur (dec n) [(*' (or optional 1) n)])))发布于 2016-09-30 11:25:58
为什么这种差异会导致错误?
简而言之,它试图分解一个长序列,它不能直接调用,它需要n个参数,然后把第一个参数( arguments
,,
,
n,把第一个参数之后的所有东西都放到一个序列中
recur对foo n的其余部分可排序的内容
我到底如何使用可选的默认参数来实现总体拥有成本?
recur的第二个参数:(defn foo [n & [optional]]
(if (= n 0) (or optional 1)
(recur (dec n) [(*' (or optional 1) n)])))
(foo 3)
;;=> 6建议
https://stackoverflow.com/questions/39782575
复制相似问题