scala-具有部分应用函数的元组类型

scala-具有部分应用函数的元组类型,scala,types,Scala,Types,谁能解释一下为什么r1类型是:(String=>String,String)而r2类型是String=>(String,String)?多谢各位 def f1(n: String, m: String): String = m + n val f2: String => String = f1(_, "something") val r1: (String => String, String) = f2 -> "foo" val r2: String => (String

谁能解释一下为什么r1类型是:
(String=>String,String)
而r2类型是
String=>(String,String)
?多谢各位

def f1(n: String, m: String): String = m + n
val f2: String => String = f1(_, "something")
val r1: (String => String, String) = f2 -> "foo"
val r2: String => (String, String) = f1(_, "something") -> "foo"
让我们看看匿名函数的语法:

val f2: String => String = f1(_, "something")
它扩展为:
(x$1:String)=>f1(x$1,“某物”)”
(用
scala-Xprint:typer开始repl

使用
f2->“foo”
,它只会变成
(f2,“foo”)
,因此
(String=>String,String)

使用
f1(,“something”)->“foo”
,其评估为:

(x:String) => f1(x,"something") -> foo
(x:String) => (f1(x,"something") , foo)
(String => (String, String))

如果混淆了占位符为什么首先计算


占位符在编译时被计算,树在编译时被调整。与
->
一样,由于隐式的原因,它在运行时被计算为元组a。

即使在阅读了Jatin的答案之后,某些事情也让我感到困惑。以下是我在进一步研究后的发现。注意,为了保存键入,我不在左手上使用类型归属ide,让Scala来推断

def f1(n: String, m: String): String = m + n

// f1: (n: String, m: String)String

val f2 = f1(_, "something") 
通常,“表达式”中的下划线表示编译器适当扩展的匿名函数。如果编译器找不到“下划线”参数的合适类型,它会抱怨如下:

// <console>:12: error: missing parameter type for expanded function ((x$1) => f1(x$1, "something"))    

val f2 = f1(_:String, "something") // Specifiying the type of the `_` as `_:String` fixes the missing parameter type error above.

// f2: String => String = <function1> 

val r1 = f2 -> "foo"
// r1: (String => String, String) = (<function1>,foo) 
val r3 = (f1(_:String, "something")) -> "foo"
r3: (String => String, String) = (<function1>,foo)
它给出函数签名String=>(String,String)

为了解决这个问题,我们在Sobral的答案中使用了第二条规则,并通过将
f1
表达式用()或{}括起来限制绑定到
\ucode>的匿名函数的范围,如下所示:

// <console>:12: error: missing parameter type for expanded function ((x$1) => f1(x$1, "something"))    

val f2 = f1(_:String, "something") // Specifiying the type of the `_` as `_:String` fixes the missing parameter type error above.

// f2: String => String = <function1> 

val r1 = f2 -> "foo"
// r1: (String => String, String) = (<function1>,foo) 
val r3 = (f1(_:String, "something")) -> "foo"
r3: (String => String, String) = (<function1>,foo)
valr3=(f1(quo:String,“something”)->“foo”
r3:(String=>String,String)=(,foo)

现在,我们得到了与
val r1=f2->“foo”

相同的结果,谢谢。这对我现在来说是有意义的。