首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尾递归函数(Coursera问题)

尾递归函数(Coursera问题)
EN

Stack Overflow用户
提问于 2015-06-21 15:53:16
回答 2查看 321关注 0票数 2

我正在学习Scala的函数式编程课程,以便学习该语言。

他们引入了尾递归函数的概念,并将其定义为以调用自身结束的函数。但是,他们把这作为一个有效的例子:

代码语言:javascript
复制
def sum(f: Int => Int)(a: Int, b: Int): Int = {
  def loop(a: Int, acc: Int): Int = {
    if (a > b) acc
    else loop(a + 1, f(a) + acc)
  }
  loop(a, 0)
}

如果我用@ tail get注释sum,就会得到一个错误,因为IDE (IntelliJ)并不认为它是尾递归的。

这里是所谓尾递归的和,还是内部实现“循环”在这里被认为是尾递归的东西?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-21 16:05:40

你是对的。sum需要调用自己,否则Scala会抱怨:

代码语言:javascript
复制
@tailrec annotated method contains no recursive calls

如果您通过将@tailrec移动到尾递归所在的位置来告诉编译器它的确切位置:

代码语言:javascript
复制
def sum(f: Int => Int)(a: Int, b: Int): Int = {
  @tailrec def loop(a: Int, acc: Int): Int = {
    if (a > b) acc
    else loop(a + 1, f(a) + acc)
  }
  loop(a, 0)
}

然后编译器将满足它是尾递归优化。

票数 2
EN

Stack Overflow用户

发布于 2015-06-21 16:00:55

内部loop方法是尾递归的,sum方法根本不是递归的.因此,您应该用loop注释@tailrec

loop移到外部范围可能有助于可视化正在发生的事情:

代码语言:javascript
复制
def sum(f: Int => Int)(a: Int, b: Int): Int = {
    loop(a, 0)
}

def loop(a: Int, acc: Int): Int = {
    if (a > b) acc
    else loop(a + 1, f(a) + acc)
}

如您所见,sum只是loop的一个公共入口点。

(请注意,上面的代码不会编译,因为loop不再在bf上关闭,但您明白了。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30966403

复制
相关文章

相似问题

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