在尝试掌握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)
}
编译器无法正确推断类型的原因是什么?有什么技巧让它起作用吗?
答案 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