scala中的隐式提升

scala中的隐式提升,scala,implicits,Scala,Implicits,我想将函数从A=>B隐式转换为List[A]=>List[B] 我写了以下隐式定义: implicit def lift[A, B](f: A => B): List[A] => List[B] = ... 不幸的是,当我编写以下代码时,隐式方法没有得到应用: val plusOne: (List[Int]) => List[Int] = (x: Int) => (x + 1) 如果我用显式时间注释函数,它可以正常工作 为什么??我怎样才能修好它 更新。这个问题似乎是

我想将函数从
A=>B
隐式转换为
List[A]=>List[B]

我写了以下隐式定义:

implicit def lift[A, B](f: A => B): List[A] => List[B] = ...
不幸的是,当我编写以下代码时,隐式方法没有得到应用:

val plusOne: (List[Int]) => List[Int] = (x: Int) => (x + 1)
如果我用显式时间注释函数,它可以正常工作

为什么??我怎样才能修好它

更新。这个问题似乎是匿名函数特有的。比较:

@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)
}
第一个编译得很好。第二个标记为错误(Scala 2.9.1-1(Java HotSpot(TM)64位服务器虚拟机,Java 1.7.0_05)

第一个观察:如果复制
fun2ListFun
并将其重命名为,例如,`fun2ListFun,您将获得

found   : String => <error>
 required: List[String] => List[Int]

Note that implicit conversions are not applicable because they are ambiguous:
 both method fun2ListFun2 of type [X, Y](f: X => Y)List[X] => List[Y]
 and method fun2ListFun of type [X, Y](f: X => Y)List[X] => List[Y]
 are possible conversion functions from String => <error> to List[String] => List[Int]
  val v: List[String] => List[Int] = ((x: String) => x.length)
进入


使编译器满意。

输入值的隐式转换会被编译。因此,匿名函数的输出存在问题

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

   val v: List[String] => Int = ((x: String) => x.length)
 }
使用第二个隐式转换的可能修复:

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

   val v: List[String] => List[Int] = ((x: String) => x.length)
 }

此版本可以编译。

编译器似乎很难弄清楚函数类型的情况。如果您能给他一点帮助,它会起作用:

scala> implicit def lift[A,B](f: A => B) = (_:List[A]).map(f)
lift: [A, B](f: (A) => B)(List[A]) => List[B]

scala> val f: List[Int] => List[Int] = ((_:Int) + 1):(Int => Int)
f: (List[Int]) => List[Int] = <function1>
scala>implicit def lift[A,B](f:A=>B)=(\u:List[A])。映射(f)
电梯:[A,B](f:(A)=>B)(列表[A])=>List[B]
scala>valf:List[Int]=>List[Int]=(((Int:Int)+1):(Int=>Int)
f:(列表[Int])=>List[Int]=
根据/Expressions/Anonymous函数(6.23):

如果匿名函数的预期类型为 函数n[S1,…,Sn,R],e的预期类型是R

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

或显式指定函数类型:

val plusOne: (List[Int]) => List[Int] = ((x: Int) => (x + 1)): Int => Int

你能提供你用来实现
隐式定义的代码吗?@ChrisJamesC用一个测试用例更新了你确定你需要/想要这样做吗?
map
为几个字符购买了很多清晰度,例如
val plusOne:(List[Int])=>List[Int]=\map(u+1)
实际上比你的版本短。
scala> implicit def lift[A,B](f: A => B) = (_:List[A]).map(f)
lift: [A, B](f: (A) => B)(List[A]) => List[B]

scala> val f: List[Int] => List[Int] = ((_:Int) + 1):(Int => Int)
f: (List[Int]) => List[Int] = <function1>
val function = (x: Int) => (x + 1)
val plusOne: (List[Int]) => List[Int] = function
val plusOne: (List[Int]) => List[Int] = ((x: Int) => (x + 1)): Int => Int