为什么 scalac 在重载 'andThen' 时会混淆我的 SAM 类型没有实现 Function?

Why scalac gets confused my SAM type not implementing Function when it overloads 'andThen'?

用 2.13 测试过,但我认为从 2.12 开始就是这样,我以前从未遇到过此类问题:

trait Extractor[-X, +Y] {
    def optional :X => Option[Y] = apply

    def apply(x :X) :Option[Y]

    def andThen[Z](extractor :Extractor[Y, Z]) :Extractor[X, Z] = {
        val first = optional; val second = extractor.optional
        Extractor { x :X => first(x).flatMap(second) }
    }

    def andThen[Z](req :Y => Z) :Extractor[X, Z] = {
        val first = optional
        Extractor { x :X => first(x).map(req) }
   }

   def compose[W](extractor :Extractor[W, X]) :Extractor[W, Y] = extractor andThen this

   def compose[W](req :W => X) :Extractor[W, Y] = Extractor(req andThen optional)

}

Scalac 对第一个 compose 的实施有一个神秘的抱怨:

Error:(44, 31) type mismatch;
found   : net.noresttherein.oldsql.morsels.Extractor[X,Y]
required: W => ?
def compose[W](extractor :Extractor[W, X]) :Extractor[W, Y] = extractor andThen this

注释掉采用函数的 andThen 变体可以解决问题。 将代码更改为 extractor.andThen[Y](this) 也是如此(显式类型参数是这里的关键)。 我的猜测是我的 SAM 类型以某种方式被提升为函数,但我猜不出为什么它会优先于方法。正如我在此处提供的两个 'solutions',我不是在寻找解决方法,而是在寻找正在发生的事情。这是多年来我第一次不明白发生了什么,并希望在未来消除类似的问题。

您可能违反了 overloading resolution 的新规则,这些规则旨在帮助类型推断。

问题是extractor.andThen(this)中arg的"expected type"是什么。

"The intuition for higher-order function parameter type inference is that all arguments must be of a function-like type."

因此删除 apply 方法会打破该条件并让输入继续进行。

规范添加:"The intent is not to steer overloading resolution."

它应该是:"The intent is not to break overloading resolution."

我想是好意铺平了道路 many roads

编辑:它在 2.12 中工作,无需修改规则。旧系统下方法重载时没有预期的类型

值得补充的是,它可能符合倒退的条件。例如,他们可以根据以前的规则进行回退类型检查。

这是一个ticket