【问题标题】:Why is this function not tail recursive?为什么这个函数不是尾递归的?
【发布时间】:2020-02-27 23:09:46
【问题描述】:

我正在为类似结构的列表编写一个简单的包含方法。我希望它针对尾递归进行优化,但无法弄清楚编译器为何抱怨。

Cons 情况是尾递归的,但不是重复情况,即使它们对相同的数据结构进行相同的调用。也许我没有正确理解尾递归。如果有人能解决这个问题,我将不胜感激。

  final def contains[B >: A](target: B): Boolean = this match{
    case Empty => false
    case Cons( h, t ) => h == target || t.contains( target )
    case Repeat( _, l ) => l.contains( target )
  } 

【问题讨论】:

    标签: scala recursion tail-recursion


    【解决方案1】:

    尾递归函数定义为最后一条语句要么返回普通值,要么调用自身,并且必须是唯一的递归调用。

    首先,您的函数没有递归调用,因为您没有再次调用contains function。但是,您正在调用另一个实例的contains 方法
    这可以通过将逻辑移到类之外来解决。

    但是,还有另一个常见问题。
    这:h == target || t.contains( target ) 不是尾递归调用,因为最后一个操作不是对 contains 的调用,而是使用其结果执行的 or (||)

    这是重构它的方法。

    def contains[A](list: MyList[A])(target: A): Boolean = {
      @annotation.tailrec
      def loop(remaining: MyList[A]): Boolean = 
        remaining match {
          case Empty => false
          case Cons(h, t) => if (h == target) true else loop(remaining = t)
          case Repeat(_, l) => loop(remaining = l)
        }
      loop(remaining = list)
    }
    

    如果你仍然想要你的类上的方法,你可以转发它来调用这个辅助函数,传递this作为初始值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-13
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多