scala-具有部分应用函数的元组类型
谁能解释一下为什么r1类型是: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
(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”
相同的结果,谢谢。这对我现在来说是有意义的。