Function Can函数尾部递归
我有一些递归代码,我想重构以使用尾部递归,我可以将递归简化为这样,请忽略此功能想要实现的功能Function Can函数尾部递归,function,scala,tail-recursion,Function,Scala,Tail Recursion,我有一些递归代码,我想重构以使用尾部递归,我可以将递归简化为这样,请忽略此功能想要实现的功能 @tailrec def doStuff: List[Int] => Int = { case Nil => 0 case x :: xs => doStuff(xs) } 如果我去掉tailrec注释,它工作得很好,结构看起来像这个doStuff(doStuff(doStuff(…))。它将有stackoverflow异常 那么,如果它是一个函数,我
@tailrec
def doStuff: List[Int] => Int = {
case Nil => 0
case x :: xs => doStuff(xs)
}
如果我去掉tailrec注释,它工作得很好,结构看起来像这个doStuff(doStuff(doStuff(…))。它将有stackoverflow异常
那么,如果它是一个函数,我怎样才能使它成为尾部递归的呢
@tailrec
def doStuff(list: List[Int]): Int = list match {
case Nil => 0
case x :: xs => doStuff(xs)
}
也许你是说这个
@tailrec
def doStuff(list: List[Int]): Int = list match {
case Nil => 0
case x :: xs => doStuff(xs)
}
匿名函数不能成为尾部递归函数。让我们首先对代码进行一次非常简单的重写,引入一个
val
来保存结果函数
@tailrec
def doStuff: List[Int] => Int = {
val result: List[Int] => Int = {
case Nil => 0
case x :: xs => doStuff(xs)
}
result
}
从这里可以清楚地看到,doStuff(xs)
并没有调用匿名函数本身。它正在调用方法doStuff
,该方法返回要调用的函数。更糟糕的是,由于它是一个def
,它实际上在每次调用时都返回不同的函数。因此,匿名函数肯定不是在调用自己
问题归结为一个简单的事实:匿名函数是匿名的。因此,他们无法直接调用自己:他们总是调用其他可能返回自己的def
或val
,但编译器不知道这一点
因此,只有像@dhg建议的那样适当的def
s才是真正的尾部递归
现在,如果您真的想返回一个函数值,它恰好是通过尾部递归案例实现的,那么您可以使用方法将一个方法转换为一个函数。因此,初始问题的解决方案如下:
val doStuff = {
@tailrec
def rec(list: List[Int]): Int = list match {
case Nil => 0
case x :: xs => rec(xs)
}
rec _
}
请注意,我们声明了一个正确的尾部递归方法(rec
),然后将其转换为带有rec
的函数值,匿名函数不能成为尾部递归函数。让我们首先对代码进行一次非常简单的重写,引入一个val
来保存结果函数
@tailrec
def doStuff: List[Int] => Int = {
val result: List[Int] => Int = {
case Nil => 0
case x :: xs => doStuff(xs)
}
result
}
从这里可以清楚地看到,doStuff(xs)
并没有调用匿名函数本身。它正在调用方法doStuff
,该方法返回要调用的函数。更糟糕的是,由于它是一个def
,它实际上在每次调用时都返回不同的函数。因此,匿名函数肯定不是在调用自己
问题归结为一个简单的事实:匿名函数是匿名的。因此,他们无法直接调用自己:他们总是调用其他可能返回自己的def
或val
,但编译器不知道这一点
因此,只有像@dhg建议的那样适当的def
s才是真正的尾部递归
现在,如果您真的想返回一个函数值,它恰好是通过尾部递归案例实现的,那么您可以使用方法将一个方法转换为一个函数。因此,初始问题的解决方案如下:
val doStuff = {
@tailrec
def rec(list: List[Int]): Int = list match {
case Nil => 0
case x :: xs => rec(xs)
}
rec _
}
请注意,我们声明了一个适当的尾部递归方法(rec
),然后使用rec
将其转换为函数值
那么,如果它是一个函数,我如何使它成为尾部递归的呢
你不能。我的意思是,当然你可以在Scala中编写一个尾部递归函数,但它不会帮助你,因为它不会得到优化
Scala只优化直尾递归方法调用
那么,如果它是一个函数,我如何使它成为尾部递归的呢
你不能。我的意思是,当然你可以在Scala中编写一个尾部递归函数,但它不会帮助你,因为它不会得到优化
Scala只优化直尾递归方法调用。不太好,它的返回类型是Int,我仍然希望返回类型是一个函数。如果您在本文中查看enumerateFile的实现。几乎所有的递归函数都不是尾部递归的。这是我想要改变的。@Cloudtech不是真的,它的返回类型是Int,我仍然希望返回类型是一个函数。如果您在本文中查看enumerateFile的实现。几乎所有的递归函数都不是尾部递归的。这是我想要改变的。@Cloudtech