首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Clojure中一起使用Default可选参数和recur

在Clojure中一起使用Default可选参数和recur
EN

Stack Overflow用户
提问于 2016-09-30 10:04:05
回答 3查看 279关注 0票数 1

我可以设置默认参数并使用它进行常规递归,但由于某些原因,我不能使用recur进行尾部优化……我一直收到一个java.lang.UnsupportedOperationException: nth not supported on this type: Long错误。

例如,对于尾部调用Factorial,以下是有效的方法,但没有针对尾部调用递归进行优化,并且对于大型递归堆栈将失败。

代码语言:javascript
复制
(defn foo [n & [optional]]
   (if (= n 0) (or optional 1)
   (foo (dec n) (*' (or optional 1) n))))

我把这个叫做(foo 3)

当我尝试这样做以获得TCO时,我得到了不受支持的操作错误...

代码语言:javascript
复制
(defn foo [n & [optional]]
   (if (= n 0) (or optional 1)
   (recur (dec n) (*' (or optional 1) n))))

我用同样的方式叫它(foo 3)

为什么这种差异会导致错误?我究竟如何使用可选的默认参数来实现总拥有成本?

谢谢!

编辑:

当我试图在递归调用中取出(or optional 1)并将其设为optional时,我得到了一个空异常错误...这是有道理的。

当我试图在递归调用中从*'中删除'时,这个问题也不会得到解决

编辑:我也更喜欢在没有loop的情况下这样做

EN

回答 3

Stack Overflow用户

发布于 2016-09-30 11:26:24

它是a known issue

递归不会重新进入函数,它只是返回到顶部(变数不会再次发生)……重复使用一个集合,你就会很好。

我个人认为它要么应该在recur文档字符串中提到,要么至少应该出现在文档中。需要一些挖掘才能理解发生了什么(我必须检查Clojure编译器源代码以及编译后的类)。

票数 2
EN

Stack Overflow用户

发布于 2016-09-30 10:50:19

你可以给一个函数赋予多个不同的特性。这可能是你要找的东西?

代码语言:javascript
复制
(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,它会起作用,但是用两个不同的符号来显式可能会更好:

代码语言:javascript
复制
(defn foo [n & [optional]]
  (if (= n 0)
    (or optional 1)
    (recur (dec n) [(*' (or optional 1) n)])))
票数 1
EN

Stack Overflow用户

发布于 2016-09-30 11:25:58

为什么这种差异会导致错误?

简而言之,它试图分解一个长序列,它不能直接调用,它需要n个参数,然后把第一个参数( arguments

  • Automatically )之后的所有东西都放入一个序列中,这个序列可以是destructured

,,

  • ,,

    • ,,
      • n,把第一个参数之后的所有东西都放到一个序列中

  • recurfoo
    • 的调用恰好有2个arguments
    • First参数:n
    • Second参数:与arguments

的其余部分可排序的内容

我到底如何使用可选的默认参数来实现总体拥有成本?

  • 只需像这样包装recur的第二个参数:

代码语言:javascript
复制
(defn foo [n & [optional]]
  (if (= n 0) (or optional 1)
  (recur (dec n) [(*' (or optional 1) n)])))

(foo 3)
;;=> 6

建议

  • 虽然他没有回答你的问题,但@DanielCompton的建议是以一种更清晰、更有效的方式从一开始就完全避免问题的方法
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39782575

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档