scala - 为什么 Scala 类型推断在这里失败?

标签 scala overloading type-inference overload-resolution

我有 this class在斯卡拉:

object Util {
  class Tapper[A](tapMe: A) {
    def tap(f: A => Unit): A = {
      f(tapMe)
      tapMe
    }

    def tap(fs: (A => Unit)*): A = {
      fs.foreach(_(tapMe))
      tapMe
    }
  }

  implicit def tapper[A](toTap: A): Tapper[A] = new Tapper(toTap)
}

现在,
"aaa".tap(_.trim)

不编译,给出错误

error: missing parameter type for expanded function ((x$1) => x$1.trim)



为什么类型不推断为 String ?从错误看来,隐式转换确实触发了(否则错误将沿着“tap 不是类 String 的成员”)。似乎转换必须是 Tapper[String] ,这意味着参数的类型是 String => Unit (或 (String => Unit)*)。

有趣的是,如果我注释掉 tap 中的任何一个定义,然后它确实编译。

最佳答案

6.26.3 Overloading Resolution

One first determines the set of functions that is potentially applicable based on the shape of the arguments

...

If there is precisely one alternative in B, that alternative is chosen.

Otherwise, let S1, . . . , Sm be the vector of types obtained by typing each argument with an undefined expected type.


tap 的两个重载是潜在适用的(基于参数的“形状”,这说明了 arity 和类型构造函数 FunctionN)。

因此,打字机继续进行:
val x = _.trim

并失败。

更智能的算法可以采用每个备选方案的相应参数类型的最小上限,并将其用作预期类型。但这种复杂性并不值得,IMO。重载有许多极端情况,这只是另一种情况。

但是在这种情况下,如果您确实需要接受单个参数的重载,则可以使用一个技巧:
object Util {
  class Tapper[A](tapMe: A) {
    def tap(f: A => Unit): A = {
      f(tapMe)
      tapMe
    }

    def tap(f0: A => Unit, f1: A => Unit, fs: (A => Unit)*): A = {
      (Seq(f0, f1) ++ fs).foreach(_(tapMe))
      tapMe
    }
  }

  implicit def tapper[A](toTap: A): Tapper[A] = new Tapper(toTap)

  "".tap(_.toString)
  "".tap(_.toString, _.toString)
  "".tap(_.toString, _.toString, _.toString)
}

关于scala - 为什么 Scala 类型推断在这里失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3315752/

相关文章:

java - 没有获取 PLAY_LANG 的正确值

scala - 如何在带有 Spark 的 Scala 中使用 countDistinct?

c++ - 避免通过操作从私有(private)构造函数间接实例化

带有 GADT 的 Haskell 类型推断和类型变量的类型类约束

c# - 为什么我必须显式提供泛型参数类型而编译器应该推断类型?

regex - 如果给定的字符串包含给定的子字符串,那么惯用的 scala 查找方式是什么?

mongodb - 如何从 Mongodb、casbah 获取数字值

C++输入重载陷入while循环

c++ - 重写 push_back C++

typescript - 处理未包装的可变元组类型