0

我一直在玩 Dotty 并尝试实现一个简单的 List。这就是我实现它的方式:

enum List[+A] {
  case Cons(head :A, tail: List[A])
  case Nil extends List[Nothing]
}

我遇到的问题是这个实现无法编译Cannot rewrite recursive call: it is not in tail position

@tailrec
def drop[A](n: Int, as: List[A]): List[A] = 
  (n,as) match
    case (0, _) => as
    case (_, Nil) => Nil
    case (x, Cons(_, tail)) => drop(x-1, tail)

在另一个文件上,我尝试了相同的实现,使用标准库的列表,它编译:

@tailrec
def drop[A](n: Int, as: List[A]): List[A] = 
  (n,as) match
    case (0, _) => as
    case (_, Nil) => Nil
    case (x, _ :: tail) => drop(x-1, tail)

也许我只是累了,没有看到明显的错误,但也许这里还有别的东西?extends List[Nothing]我必须添加以使代码编译引起的任何奇怪之处?

谢谢!

编辑

4

1 回答 1

3

在 Dotty 0.25.0-bin-20200429-c5a76f0-NIGHTLY

import scala.annotation.tailrec

enum List[+A] {
  case Cons(head :A, tail: List[A])
  case Nil extends List[Nothing]

  @tailrec
  def drop[A](n: Int, as: List[A]): List[A] =
    (n,as) match
      case (0, _) => as
      case (_, Nil) => Nil
      case (x, Cons(_, tail)) => drop(x-1, tail)
}

生产

TailRec optimisation not applicable, method drop is neither private nor final so can be overridden

如果您将drop其设为 final 或 private,则代码会编译。

于 2020-04-30T19:58:14.270 回答