我遇到了隐式转换和高阶函数的问题。似乎只有转换函数至少有两个参数,才能将函数隐式转换为二阶函数。
使用:
implicit def conv(foo: Integer => String): String => String = null
不起作用:
implicit def conv(foo: Integer => String): String => String => String = null
使用:
implicit def conv(foo: (Integer, Integer) => String): String => String => String = null
失败点的完整示例:
{
implicit def conv(foo: Integer => String): String => String = null
def baadf00d(foo: Integer): String = null
def deadbeef(foo: String => String) = null
deadbeef(conv(baadf00d))
deadbeef(baadf00d)
}
{
implicit def conv(foo: Integer => String): String => String => String = null
def baadf00d(foo: Integer): String = null
def deadbeef(foo: String => String => String) = null
deadbeef(conv(baadf00d))
deadbeef(baadf00d) // <-------- DOES NOT COMPILE!
}
{
implicit def conv(foo: (Integer, Integer) => String): String => String => String = null
def baadf00d(foo: Integer, bar: Integer): String = null
def deadbeef(foo: String => String => String) = null
deadbeef(conv(baadf00d))
deadbeef(baadf00d)
}
我错过了什么?
谢谢!
答案 0 :(得分:3)
implicit def conv(foo: Integer => String): String => String => String = ???
def baadf00d(i: Integer): String = ???
def goodf00d: Integer => String = _ => ???
def deadbeef(foo: String => String => String) = ???
deadbeef(conv(baadf00d))
deadbeef(baadf00d) // <-------- DOES NOT COMPILE!
deadbeef(goodf00d) // <-------- COMPILE!
// ¯\_(ツ)_/¯
问题是隐式转换如何对Scala起作用以及Scala中存在curried和uncurried函数的事实。
这应该是可行的,但不是,并且可能只是另一个编译器错误(随着越来越多地使用Scala,准备好再遇到更多)。
编辑:至于你的上一个例子
implicit def conv(foo: (Integer, Integer) => String): String => String => String = null
def baadf00d(foo: Integer, bar: Integer): String = null
def deadbeef(foo: String => String => String) = null
那是因为函数定义匹配。 conv期望函数(Int, Int) => String
和scala中的正常方法定义(uncurried),就像定义baadf00d
的方式一样,变成了那个。
例如,一个函数:
def f(a: Int, b: Int): String
变成了
(Int, Int) => String
请注意,2个Int是tupled!这与以下内容不同:
Int => Int => String
如果您要将baadf00d重新定义为:
def baadf00d: Integer => Integer => String = _ => _ => ???
该代码不会编译,因为baadf00d现在是&#34;不同&#34;,即使它正在做同样的事情。
有关更多信息,请查看对象的定义:
Function1, Function2, Function3 ....
答案 1 :(得分:-1)
implicit def conv1(a: Function1[Int, String]): Function2[String, String, String] = null
def baadf00d1(i: Int): String = null
def deadbeef1(arg: Function2[String, String, String]) = null
deadbeef(baadf00d) // compiles
这是A => B
和Function1[A,B]
之间未发生的转换。
Function
中还有Predef
类型 - 请注意此处的类型差异:
scala> val f1: Function[Int, Int] = null
f1: Function[Int,Int] = null
scala> val f2: Function1[Int, Int] = null
f2: Int => Int = null
scala> :type f1
Function[Int,Int]
scala> :type f2
Int => Int
它是Function1
的别名,但具有不同的类型范围(如下面的评论中所述)。