斯卡拉隐含的提升

Kon*_*tov 5 scala implicits

我想隐式地将函数转换A => BList[A] => List[B].

我写了以下隐含的定义:

implicit def lift[A, B](f: A => B): List[A] => List[B] = ...
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我编写以下代码时,隐式不会被应用:

val plusOne: (List[Int]) => List[Int] = (x: Int) => (x + 1)
Run Code Online (Sandbox Code Playgroud)

如果我用显式时间注释函数,它工作正常.

为什么?我该如何解决?

UPDATE.似乎问题是匿名函数特有的.相比:

@Test
def localLiftingGenerics {
  implicit def anyPairToList[X, Y](x: (X, Y)): List[X] => List[Y] = throw new UnsupportedOperationException  

  val v: List[String] => List[Int] = ("abc", 239)
}

@Test
def localLiftingFuns {
  implicit def fun2ListFun[X, Y](f: X => Y): List[X] => List[Y] = throw new UnsupportedOperationException

  val v: List[String] => List[Int] = ((x: String) => x.length)
}
Run Code Online (Sandbox Code Playgroud)

第一个编译得很好.第二个标记为错误

Pav*_*tin 6

根据Scala语言规范 /表达式/匿名函数(6.23):

如果匿名函数的预期类型的​​形式为scala.Function n [ S 1,...,S n,R ],则e的预期类型为R ...

因此,List[Int]除非您将函数定义与函数值赋值分开(以消除期望的类型),否则将推断函数的结果类型:

val function = (x: Int) => (x + 1)
val plusOne: (List[Int]) => List[Int] = function
Run Code Online (Sandbox Code Playgroud)

或明确指定函数类型:

val plusOne: (List[Int]) => List[Int] = ((x: Int) => (x + 1)): Int => Int
Run Code Online (Sandbox Code Playgroud)