Scala 当我只向一个curried函数传递一个参数时,为什么它能成功编译?

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]) {

为什么第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]) {
    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)
的结果是一个您试图分配给变量的方法,因此要求您添加一个
,如上例所述