【发布时间】:2022-01-24 06:23:25
【问题描述】:
下面,sumAllIf 是尾递归的,sumAllFold 不是。但是,sumAllIf 实际上具有相同的实现。这是 Scala 编译器(或 Scala 库)的缺点,还是我忽略了什么?
def maybeNext(in: Int): Option[Int] = if in < 10 then Some(in + 1) else None
// The Scala library implements Option.fold like this:
// @inline final def fold[B](ifEmpty: => B)(f: A => B): B =
// if (isEmpty) ifEmpty else f(this.get)
@annotation.tailrec
def sumAllIf(current: Int, until: Int, sum: Int): Int =
val nextOption = maybeNext(current)
if (nextOption.isEmpty) sum else sumAllIf(nextOption.get, until, sum + nextOption.get)
// However, with Scala 3.1.0 and earlier, this is NOT tail recursive:
def sumAllFold(current: Int, until: Int, sum: Int): Int =
maybeNext(current).fold(sum)(next => sumAllFold(next, until, sum + next))
@main def main(): Unit =
println(sumAllIf(0, 10, 0))
println(sumAllFold(0, 10, 0))
这个问题类似于问题Scala @tailrec with fold,但在这里我想了解一下为什么以及这是否可以将来会得到支持。
该示例适用于 Scala 3.1,但问题本身也适用于 Scala 2.x。
-
从您附加的链接中的答案; \"... Scala 编译器无法计算出折叠的结果\" 因为编译器无法计算出折叠的结果,因此无法使其尾递归。
-
这来自尾递归的定义。该调用不在尾部位置,并且如果没有内联,编译器对于如何优化它并不明显。如果您真的需要尾递归,请自己编写递归。
-
这回答了你的问题了吗? Scala @tailrec with fold
标签: scala tail-recursion fold