Scala 只有当要转换的函数至少有两个参数时,才能将函数隐式转换为二阶函数

Scala 只有当要转换的函数至少有两个参数时,才能将函数隐式转换为二阶函数,scala,implicit-conversion,higher-order-functions,Scala,Implicit Conversion,Higher Order Functions,我有一个隐式转换和高阶函数的问题。似乎只有当要转换的函数至少有两个参数时,函数到二阶函数的隐式转换才有效 作品: implicit def conv(foo: Integer => String): String => String = null implicit def conv(foo: (Integer, Integer) => String): String => String => String = null 不起作用: implicit def co

我有一个隐式转换和高阶函数的问题。似乎只有当要转换的函数至少有两个参数时,函数到二阶函数的隐式转换才有效

作品:

implicit def conv(foo: Integer => String): String => String = null
implicit def conv(foo: (Integer, Integer) => String): String => String => String = null
不起作用:

implicit def conv(foo: Integer => String): String => String => String = null
作品:

implicit def conv(foo: Integer => 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)
}
{
隐式def conv(foo:Integer=>String):String=>String=null
def baadf00d(foo:Integer):字符串=null
def deadbeef(foo:String=>String)=null
死牛肉(conv(baadf00d))
死牛肉(baadf00d)
}
{
隐式def conv(foo:Integer=>String):String=>String=>String=null
def baadf00d(foo:Integer):字符串=null
def deadbeef(foo:String=>String=>String)=null
死牛肉(conv(baadf00d))
死牛肉(baadf00d)//String:String=>String=>String=null
def baadf00d(foo:Integer,bar:Integer):字符串=null
def deadbeef(foo:String=>String=>String)=null
死牛肉(conv(baadf00d))
死牛肉(baadf00d)
}
我错过了什么

谢谢

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]
之间没有发生的转换

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
的别名,但具有不同的类型边界(如下面的注释所指出的)

这是因为函数定义不匹配。conv需要一个函数
(Int,Int)=>String
,scala中的一个普通方法定义(未载波)变成了这个函数,就像
baadf00d
是如何定义的一样

例如,函数:

def f(a: Int, b: Int): String
变成了一个

(Int, Int) => String
请注意,2个整数是元组!这与:

Int => Int => String
如果要将baadf00d重新定义为:

def baadf00d: Integer => Integer => String = _ => _ => ???
该代码不会编译,因为baadf00d现在“不同”,即使它正在做相同的事情

有关详细信息,请查看对象的定义:

Function1, Function2, Function3 ....

或者您甚至可以使用
val baadf00d2=baadf00d\uucode>将
baadf00d
分配给val,然后它工作:type和:kind在REPL中统一对待它们,使其看起来更奇怪。from Predef.scala“type Function[-a,+B]=Function1[a,B]”你认为类型边界的差异会使它与上面例子中的implicit不匹配吗?
Function1[A,B]
A=>B
是同一件事(在类型上下文中)。在我看来,它就像Scala中的隐式解析。这是哪个Scala版本?好的,所以第二次转换不起作用的原因只是因为一个编译器错误,我猜…是的。在Scala中,
baadf00d
goodf00d
应分别转换为
(Int)=>String
Int=>String
。现在这些事情应该是一样的,但出于某种原因,隐式决断认为它们是不同的。您可以将
baadf00d
传递到
conv
中,这一事实证明它们是相同的,只是隐式解析太愚蠢了,无法理解它。