Scala类型推断隐式解析匿名函数

时间:2016-03-24 21:11:13

标签: scala types type-conversion

在尝试掌握Scala implicits时,我遇到了这种类型的推理问题:

object Demo extends App {

  def demo(f: (Int, Int) => Int) = ???

  demo((a: Int) => 42)
  demo((a) => 42) // <-- any tricks to make this compile?

  implicit def f1Tof2(f: Int => Int): (Int, Int) => Int =
    (a: Int, b: Int) => f.apply(a)

}

编译器无法正确推断类型的原因是什么?有什么技巧让它起作用吗?

1 个答案:

答案 0 :(得分:3)

这是不可能的。当您调用demo((a, b) => a + b)(例如)时,编译器已经期望(Int, Int) => Int,因此它会将(a, b) => a + b推断为(Int, Int) => Int,因为它具有正确的形状。

但是,当您调用demo(a => 42)时,编译器会将Function1[?, Int]视为参数,而不指示参数类型是什么。由于demo需要Function2,因此编译的唯一方法是编译器可以找到从传递的参数类型到(Int, Int) => Int的隐式转换。但它不能,因为它不知道它从转换的类型。它不能只假设它是Int => Int

只有两种方法可以完成这项工作。

1。)明确声明匿名函数的参数类型,就像您已经完成的那样。这是可以应用隐式转换的唯一方法。

demo((a: Int) => 42)

2。)为demo提供接受Int => Int的重载。

def demo(f: (Int, Int) => Int): Int = f(1, 2)
def demo(f: Int => Int): Int = demo((a, b) => f(a))

scala> demo(a => 42)
res3: Int = 42