简体   繁体   English

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

[英]Scala type inference of implicitly resolved anonymous functions

While trying to grasp Scala implicits, I ran into this type inference problem: 在尝试掌握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)

}

What's the reason behind the compiler's inability to infer the type correctly? 编译器无法正确推断类型的原因是什么? Any tricks to make it work? 任何使其有效的技巧?

This isn't possible. 这是不可能的。 When you call demo((a, b) => a + b) (for example), the compiler is already expecting an (Int, Int) => Int , so it will infer (a, b) => a + b as (Int, Int) => Int , since it has the correct shape. 当您调用demo((a, b) => a + b) (例如)时,编译器已经期望(Int, Int) => Int ,因此它将推断(a, b) => a + b as (Int, Int) => Int ,因为它具有正确的形状。

However, when you call demo(a => 42) , the compiler sees a Function1[?, Int] as the argument, with no indication as to what the parameter type is. 但是,当您调用demo(a => 42) ,编译器会将Function1[?, Int]视为参数,而不指示参数类型是什么。 Since demo expects a Function2 , the only way this can compile is if the compiler can find an implicit conversion from the passed argument type to (Int, Int) => Int . 由于demo需要一个Function2 ,因此编译器可以找到从传递的参数类型到(Int, Int) => Int的隐式转换的唯一方法。 But it can't, because it doesn't know the type it's converting from . 但它不能,因为它不知道它是转换的类型。 It cannot just assume it will a Int => Int . 它不能只假设它将是Int => Int

There are only two ways to make this work. 只有两种方法可以完成这项工作。

1.) Explicitly declare the parameter type of the anonymous function, like you have done already. 1.)明确声明匿名函数的参数类型,就像您已经完成的那样。 This is the only way the implicit conversion can be applied. 这是可以应用隐式转换的唯一方法。

demo((a: Int) => 42)

2.) Provide an overload for demo that accepts a Int => Int . 2.)为接受Int => Int demo提供重载。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM