Scala 中的匿名递归函数
有没有办法在 Scala 中编写递归的匿名函数?我正在考虑这样的事情:(
((t: Tree) => {
print(t.value);
for (c <- t.children)
thisMethod(c)
})(root)
相关问题:哪些语言支持*递归*函数文字/匿名函数?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
正如您发布的链接中所述。您可以使用 Y 组合器。这是示例:
请注意,它不适用于大数字。
小心尾部调用优化。
As described in the link you posted. You can use Y-combinator. Here is example:
Note it doesn't work with big numbers.
Be careful with tail call optimization.
如果你不想学习“神奇的数学”,你可以回到 scala 的对象方面。
If you don't want to hit the "Amazing mathematics" you could just revert to the object aspects of scala.
为了使它看起来更极客,您还可以使用以下代码风格:
in order to make it look geekier you can also use this code style:
除了本线程中的许多良好响应之外,Scala 没有为我们提供尾部调用可优化定点组合器这一事实一直困扰着我,因此我决定编写一个宏来转换类似 Y 组合器的调用到一个普通的、惯用的递归调用(当然,带有尾调用优化)。这个想法是,像这样的调用
很容易翻译成
我已经将针对 Scala 2.11 的宏实现(稍作调整也应该适用于 2.10)转换为 这个要点。
使用这个宏,我们可以以匿名方式执行普通的递归任务,而不必担心堆栈溢出,例如
给出
Adding to the many good responses here in this thread, the fact that Scala is not giving us tail call optimizable Fixed-point combinator has been bothering me so much so that I've decided to write a macro to translate Y-combinator-like call to an ordinary, idiomatic recursive call (with tail call optimization, of course). The idea is that a call like
is readily translatable into
I've put up macro implementation targeting Scala 2.11 (with minor tweak should also work with 2.10) into this gist.
With this macro, we can perform ordinary recursive tasks in anonymous manner without fearing stack overflow e.g.
gives
Scala 上的递归调用。
让我以 N 个数字之和为例进行递归
您可以看到 sumIt 的类型为 Int,Int 作为输入和返回值。 sumIt lambda 函数采用 Integer 作为参数,并对 sumIt 进行递归调用。
Recursive calls on Scala.
Let me take sum of N numbers example for recursion
You can see the sumIt has its type with Int, Int as Input and the return value. The sumIt lambda function takes as argument which is an Integer and it does recursive call on sumIt.
添加到 @in-ho-yi 的答案。为简单起见,您可以直接在匿名函数内部定义本地函数并将其用于递归。另外,在本地函数之前使用 @tailrec 可以确保它将应用尾递归,而 Y 组合器无法做到这一点。
这是比 Y-combinator 更好的方法,因为它只向堆栈添加 2 帧,并且每次调用函数时添加 1 帧(如果不是尾递归,则总共只会添加 1 帧,因此最多将使用 3 帧)而不是 Y-combinator 使用的每次调用 6 个
To add onto @in-ho-yi 's answer. For simplicity you can directly define a local function inside of an anonymous function and use it for recursion. Also using
@tailrec
before the local function you can make sure it will apply tail recursion which you can't do with the Y-combinator.This is a better approach than Y-combinator because it only adds 2 frames to the stack and 1 per call of the function (if it's not tail recursive, if it is it will only add 1 in total so 3 frames max will be used) instead of 6 per call that Y-combinator uses
一个非常简单的方法:
A very simple approach: