Scala my函数的扩展函数缺少参数类型;不适用于具有相同签名的其他人

Scala my函数的扩展函数缺少参数类型;不适用于具有相同签名的其他人,scala,lambda,pattern-matching,function-literal,Scala,Lambda,Pattern Matching,Function Literal,缩写形式:我有一个与Future.recover具有相同签名的方法。将部分函数传递给未来的版本是可行的。将相同的PF传递给我的版本会导致扩展函数的参数类型丢失。匿名函数的参数类型必须完全已知。(SLS 8.5)错误。有什么区别 较长的表格: 我正在尝试实现所讨论的TracingFuture类,试图跨未来边界跟踪错误。基本技术是在添加伪stacktrace的同时,将Future封装在另一个类中,TracingFuture 博客文章中给出的代码缺少来自Future的recover方法,因此我添加了相

缩写形式:我有一个与
Future.recover具有相同签名的方法。将部分函数传递给未来的
版本是可行的。将相同的PF传递给我的版本会导致扩展函数的
参数类型丢失。匿名函数的参数类型必须完全已知。(SLS 8.5)
错误。有什么区别

较长的表格: 我正在尝试实现所讨论的
TracingFuture
类,试图跨未来边界跟踪错误。基本技术是在添加伪stacktrace的同时,将Future封装在另一个类中,
TracingFuture

博客文章中给出的代码缺少来自
Future
recover
方法,因此我添加了相同的签名:

class TracingFuture[+T](underlying: Future[T], val trace: Vector[FutureTraceElement]) extends Future[T] {

  def recover[U >: T](pf: PartialFunction[Throwable, U]
                     )(implicit ec: ExecutionContext, enclosing: sourcecode.Enclosing, file: sourcecode.File,
                       line: sourcecode.Line): TracingFuture[U] = {
    val recovered = underlying.recover(pf)
    new TracingFuture[U](recovered, trace :+ FutureTraceElement(enclosing.value, "recover", file.value, line.value))

  }

}
为了进行比较,这里是
Future
中的等效代码块。请注意,除了额外的隐式参数外,签名是相同的

trait Future[+T] extends Awaitable[T] {

  def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] =
    transform { _ recover pf }
}
最后,我的代码生成编译错误:

val x: TracingFuture[Vector[Maintainer]] = ... // code producing a TracingFuture
val fMaintainers = x.recover {
  case err: Throwable ⇒
    logger.error("Failed to get list of user maintainers.", err)
    Vector.empty[Maintainer]
}
以及错误消息:

[error] /Users/bwbecker/oat/src/oat3/modules/wapp/app/oat/wapp/dao/CronJobDAO.scala:273: missing parameter type for expanded function
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ?
[error]     val fMaintainers = x.recover {
[error]                                  ^
同样,这段代码与
Future.recover
一起工作,但我在
TracingFuture.recover
中遇到编译错误。我不明白为什么

说明编译器知道分部函数的参数必须是T的超类型,但不能保证这一点。但是为什么它在
Future.recover中没有遇到这个问题呢

当然,我想知道除了重写匿名部分函数以使类型显式化之外,我是否还有其他方法

val fMaintainers = x.recover {
  case err: Throwable ⇒
    logger.error("Failed to get list of user maintainers.", err)
    Vector.empty[Maintainer]
}


问题在于
TracingFuture
有两个重载的
recover
方法:您添加的方法和从
Future
继承的方法。当您只有一个时,它提供了对类型推断至关重要的预期类型,但是对于重载方法,它不起作用,正如您从
中看到的,预期类型是:?

您可能认为编译器应该注意函数参数的类型是相同的,因此仍然可以提供预期的类型。你是对的,但是


当然,如果只有隐式参数不同,编译器就无法判断您需要哪个重载,这会给您带来麻烦。

那里的答案似乎与这个问题无关,除非我遗漏了什么。Dmytro,感谢您快速而翔实的回答。我需要决定是重命名恢复函数的版本,还是按照您的建议对类型进行注释。仍然在思考这个问题…谢谢你,亚历克赛,给了我快速而翔实的答复。我给了恢复方法一个不同的名称,正如您在这里所说的那样,编译错误消失了。
val fMaintainers = x.recover(PartialFunction[Throwable, Vector[Maintainer]] { 
  case err: Throwable ⇒
    logger.error("Failed to get list of user maintainers.", err)
    Vector.empty[Maintainer]
})