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