Scala Curried Type Mismatch

joa*_*him 4 scala currying

因此,经过一些试验和错误以及我们的教科书中的研究后,我得到了以下功能,我可以想出一个解决方案.

def prodC1(f : Int => Int) : (Int, Int) => Int = {
  def prodA1(a : Int, b : Int) : Int =
    if(a > b) 1 else f(a) * prodA1(a+1, b)
  prodA1 // Why do i need this line here 
}
Run Code Online (Sandbox Code Playgroud)

如果我没有把它放在那里我得到类型不匹配,有人可以详细说明/解释这条线的要求吗?

Sar*_*ngh 6

所以你需要知道许多事情才能真正理解这个问题的答案.

在Scala中,任何def一个method只不过是其中一个成员object.methods不是Scala中的头等成员,这也意味着它们methods不能独立存在.

在Scala中,value任何事物都需要成为一个expression.意味着RHS def需要像一个表达式def abc = some-expression.表达的实例是1,1 + 1,"xyz",anotherMethodCallWhichWillReturnAnExpression()等.

类似的东西def abc = xxxxxx不是expressionScala语言的定义.因此你做不到,

def prodC1(f : Int => Int) : (Int, Int) => Int = {
  def prodA1(a : Int, b : Int) : Int =
    if(a > b) 1 else f(a) * prodA1(a+1, b)
}
Run Code Online (Sandbox Code Playgroud)

现在,当你添加额外的行时prodA1,你告诉Scala返回prodA1你刚刚定义的那个.但记住prodA1只是一个method,因此不能单独存在,因此实际上不能返回.

但是functionsScala中的第一类成员(表示为各种FunctionX类之一的实例)因此可以返回.

在这种情况下斯卡拉会智能地提升这个method成为一个function类型的(Int, Int) => Int.这称为eta-expansion.

更详细地了解事情.您可以打开Scala控制台并尝试以下操作.

scala> val s = "abc"
// s: String = abc

scala> val i = 10
// i: Int = 10


scala> def prodA1(a : Int, b : Int) : Int = if (a > b) 1 else a * prodA1(a+1, b)
// prodA1: (a: Int, b: Int)Int
Run Code Online (Sandbox Code Playgroud)

注意Scala控制台输出与实际valuesdef.之间的区别.现在,如果我尝试使用prodA1作为valueval,我会得到下面的错误.

scala> val x = prodA1
// <console>:12: error: missing argument list for method prodA1
// Unapplied methods are only converted to functions when a function type is expected.
// You can make this conversion explicit by writing `prodA1 _` or `prodA1(_,_)` instead of `prodA1`.
//        val x = prodA1
Run Code Online (Sandbox Code Playgroud)

Scala告诉您,您可以使用a 显式转换method为.让我们试试吧.function_

scala> val x = prodA1 _
// x: (Int, Int) => Int = $$Lambda$1077/293669143@13278a41
Run Code Online (Sandbox Code Playgroud)

现在x是一种function类型(Int, Int) => Int.

此外,第一行Unapplied methods are only converted to functions when a function type is expected.告诉您案件中实际发生的事情.

由于prodC1预计会返回一种function类型(Int, Int) => Int并且您提供prodA1,Scala用于eta-expansion自动转换methodfunction.