1

以下のコード (非常に些細な最大値とリストの合計) では、メソッドの最後で呼び出される再帰関数があります。scala コンパイラはこれを末尾再帰として扱い、スタック フレームの使用を最適化しますか? これを確認するにはどうすればよいですか?

package example

import common._

object Lists {
  def sum(xs: List[Int]): Int = {

    def recSum(current: Int, remaining: List[Int]): Int = {
      if (remaining.isEmpty) current else recSum(current + remaining.head, remaining.drop(1))
    } 

    recSum(0, xs)
  }

  def max(xs: List[Int]): Int = {

    def recMax(current: Int, remaining: List[Int], firstIteration: Boolean): Int = {
      if(remaining.isEmpty){
        current
      }else{
        val newMax = if (firstIteration || remaining.head>current) remaining.head else current
        recMax(newMax, remaining.drop(1), false)
      }
    }

    if (xs.isEmpty) throw new NoSuchElementException else recMax(0, xs, true)
  }
}
4

1 に答える 1

4

関数定義の前に追加@tailrecして、コンパイラが非末尾再帰メソッドでエラーを発生させるようにします:)また、この方法で最適化した場合、関数が命令型ループ(別名for/whileループ)と同じくらい効率的であると想定する必要がありますコンパイラによって。

于 2013-03-29T19:33:58.143 に答える