有没有一种方法可以在Scala中编写一个递归的匿名函数?我正在考虑这样的事情:
((t: Tree) => {
print(t.value);
for (c <- t.children)
thisMethod(c)
})(root)
(相关问题:Which languages support recursive function literals / anonymous functions?)
有没有一种方法可以在Scala中编写一个递归的匿名函数?我正在考虑这样的事情:
((t: Tree) => {
print(t.value);
for (c <- t.children)
thisMethod(c)
})(root)
(相关问题:Which languages support recursive function literals / anonymous functions?)
7条答案
按热度按时间elcex8rz1#
如您发布的链接中所述。您可以使用Y-组合器。下面是示例:
注意它不适用于大的数字。小心尾部调用优化。
uz75evzq2#
如果你不想达到“惊人的数学”,你可以回到scala的对象方面。
uajslkp63#
为了让它看起来更极客,你也可以使用这种代码风格:
vwoqyblh4#
除了这个线程中的许多好的响应之外,Scala没有给我们提供尾部调用优化的定点组合子这个事实一直困扰着我,以至于我决定写一个宏来将类似Y组合子的调用转换为普通的、惯用的递归调用(当然有尾部调用优化)。
很容易被翻译成
我已经把针对Scala 2.11的宏实现(稍微调整一下也可以在2.10中工作)放到了this gist中。
有了这个宏,我们可以以匿名的方式执行普通的递归任务,而不用担心堆栈溢出。
给予
kmynzznz5#
Scala上的递归调用。让我以N个数的和为例进行递归
你可以看到sumIt的类型是Int,Int作为输入,返回值是。sumIt lambda函数的参数是一个Integer,它递归调用sumIt。
我只是这个例子,以便于理解递归调用。你可以直接公式为这个逻辑像…
bfrts1fy6#
添加到@in-ho-yi的answer上。为了简单起见,你可以直接在匿名函数中定义一个局部函数,并使用它进行递归。在局部函数之前使用
@tailrec
,你可以确保它会应用尾部递归,这是你不能用Y组合子来做的。这是一个比Y-combinator更好的方法,因为它只向堆栈添加2帧,每次调用函数只添加1帧(如果不是尾递归,如果是尾递归,则总共只添加1帧,因此最多将使用3帧),而不是Y-combinator使用的每次调用6帧
von4xj4u7#
一个非常简单的方法: