Scala 当我只向一个curried函数传递一个参数时,为什么它能成功编译?
为什么第8行编译成功而第15行没有编译?这两行代码之间有什么区别Scala 当我只向一个curried函数传递一个参数时,为什么它能成功编译?,scala,Scala,为什么第8行编译成功而第15行没有编译?这两行代码之间有什么区别 package test object TestCurrying { def multiply(x: Int)(y: Int): Int = x * y def invoke(f: Int => Int => Int): Int = { val f1 = f(1) //Compile success f1(2) } def main(args: Array[String]) {
package test
object TestCurrying {
def multiply(x: Int)(y: Int): Int = x * y
def invoke(f: Int => Int => Int): Int = {
val f1 = f(1) //Compile success
f1(2)
}
def main(args: Array[String]) {
val res = invoke(multiply)
val f1 = multiply(1)//Compile fail
}
}
在gitter上由tpolecat解决,非常感谢他。以下是他伟大的答案: 这里发生了一些事情。您可以将一个方法转换为 函数通过η展开。表达式multiply u将为您提供一个 委托给方法的Int=>Int=>Int类型的函数值。 在预期使用这种函数类型的上下文中,编译器将 为你做这件事。这就是当你说 调用(乘法)。您可以只应用一部分curried函数 很好,正如你在f(1)中看到的。您不能使用curry方法来执行此操作 (除非在预期为该类型的上下文中);给你 需要说乘法(1)_ 但是,乘法(1):(Int=>Int)会起作用,因为 为编译器提供有关预期类型的详细信息
在gitter上由tpolecat解决,非常感谢他。以下是他伟大的答案: 这里发生了一些事情。您可以将一个方法转换为 函数通过η展开。表达式multiply u将为您提供一个 委托给方法的Int=>Int=>Int类型的函数值。 在预期使用这种函数类型的上下文中,编译器将 为你做这件事。这就是当你说 调用(乘法)。您可以只应用一部分curried函数 很好,正如你在f(1)中看到的。您不能使用curry方法来执行此操作 (除非在预期为该类型的上下文中);给你 需要说乘法(1)_ 但是,乘法(1):(Int=>Int)会起作用,因为 为编译器提供有关预期类型的详细信息
这个问题的答案在于方法和函数之间的区别。不过,这与咖喱没有多大关系 现在,
multiply
是一种方法。当我们将一个方法传递给另一个方法(在本例中为调用
)时,它会自动提升
到一个函数。此提升通过eta扩展完成。
Scala方法是类的一部分。它有一个名字,一个签名,一个身体。
Scala中的函数是一个完整的对象。Scala中有一系列特性可以表示具有不同数量参数的函数:Function0、Function1、Function2等。
请参阅更多详细信息
scala提供的将方法转换或提升为函数的方法是\uu
运算符
说你有办法
def testMethod(n:Int){
//insert code here
}
你有台词吗
val testf = testMethod(4)
这一行意味着调用方法testMethod
。
但是如果我写,
val testf = testMethod
这意味着我没有调用或调用该方法,而是将该方法分配给变量testf
。这个赋值
操作意味着我们要将该方法视为一个函数
即一个完整的整体。编译器会抱怨上面的代码行,并建议您在测试方法中添加
因此我们需要写,
val testf=testMethod
使赋值成功,从而将方法
提升为一个函数。
出于同样的原因,在你的代码中
val f1=multiply(1)
不起作用,因为编译器发现multiply(1)
的结果是一个您试图分配给变量的方法,因此要求您添加一个
,如上例所述。这个问题的答案在于方法和函数之间的区别。不过,这与咖喱没有多大关系
现在,multiply
是一种方法。当我们将一个方法传递给另一个方法(在本例中为调用
)时,它会自动提升
到一个函数。此提升通过eta扩展完成。
Scala方法是类的一部分。它有一个名字,一个签名,一个身体。
Scala中的函数是一个完整的对象。Scala中有一系列特性可以表示具有不同数量参数的函数:Function0、Function1、Function2等。
请参阅更多详细信息
scala提供的将方法转换或提升为函数的方法是\uu
运算符
说你有办法
def testMethod(n:Int){
//insert code here
}
你有台词吗
val testf = testMethod(4)
这一行意味着调用方法testMethod
。
但是如果我写,
val testf = testMethod
这意味着我没有调用或调用该方法,而是将该方法分配给变量testf
。这个赋值
操作意味着我们要将该方法视为一个函数
即一个完整的整体。编译器会抱怨上面的代码行,并建议您在测试方法中添加
因此我们需要写,
val testf=testMethod
使赋值成功,从而将方法
提升为一个函数。
出于同样的原因,在你的代码中
val f1=multiply(1)
不起作用,因为编译器发现multiply(1)
的结果是一个您试图分配给变量的方法,因此要求您添加一个
,如上例所述