scala - 无法重写递归调用:它不在尾部位置
问题描述
我一直在玩 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]
我必须添加以使代码编译引起的任何奇怪之处?
谢谢!
编辑:
解决方案
在 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,则代码会编译。
推荐阅读
- wpf - 使用 WebBrowser 控件创建 WPF 应用程序的限制
- mongodb - 如何修复带有未知 GeoJSON 类型错误的 MongoDB 地理键错误?
- ios - 视图控制器中的多个集合视图 - 不为所有集合设置委托
- logic - 命题逻辑推理方式
- python - 使用 with 语句创建 stem.control.Controller 对象是否有意义?
- mysql - 反应原生 Promise 拒绝。网络请求失败(如何获取数据)
- javascript - 具有指定过期时间的持久客户端数据存储
- java - 两栈的 Hackerrank 博弈
- electron - 有没有办法生成只是铬浏览器的电子浏览器窗口?
- apache-kafka - 首选副本和领导者可以是不同的经纪人吗?