Scala Curried 类型不匹配
Scala Curried Type Mismatch
经过反复试验和研究我们的教科书后,我得到了以下功能,我可以想出一个解决方案。
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
}
如果我不把它放在那里,我会得到类型不匹配,有人可以 elaborate/explain 这条线的要求吗?
您的函数需要 return (Int, Int) => Int 的一个实例。
def prodA1(a : Int, b : Int) : Int =
if(a > b) 1 else f(a) * prodA1(a+1, b)
创建一个 (Int, Int) => Int
类型的函数,名称为 prodA1,但 return 类型的 定义 内部函数不会创建任何实例,因此return 函数的类型是 Unit
.
因此您需要 return 具有正确类型的 prodA1
..
我们来看看你的 return 类型。
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
}
你的return类型是
(Int, Int) => Int
这是 Function2[Int, Int, Int]
的 scala 糖
其中第一个参数是第一个参数的类型,第二个参数是第二个参数的类型,最后一个是 return 参数的类型
return 实例需要是一个函数
prodA1 符合此类型,意味着它可以被 returned。
所以你需要知道很多事情才能真正理解这个问题的答案。
在 Scala 中,任何 def
都是一个 method
,它只不过是一些 object
的成员之一。 methods
不是 Scala 中的第一个 class 成员,这也意味着 methods
不能独立存在。
在 Scala 中,任何东西的 value
都需要是 expression
。这意味着 def
的 RHS 需要像 def abc = some-expression
这样的表达式。表达式的例子有1
、1 + 1
、"xyz"
、anotherMethodCallWhichWillReturnAnExpression()
等
并且像 def abc = xxxxxx
这样的东西在 Scala 语言定义中不是 expression
。因此你不能这样做,
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
添加额外的行时,您是在告诉 Scala return 您刚刚定义的这个 prodA1
。但请记住 prodA1
只是一个 method
,因此不能单独存在,因此实际上不能被 returned。
但是 functions
是 Scala 中的第一个 class 成员(表示为各种 FunctionX
classes 之一的实例)因此可以是 returned.
在这种情况下,Scala 会智能地将此 method
提升为类型 (Int, Int) => Int
的 function
。这称为 eta 扩展。
更详细地了解事物。您可以打开 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
请注意实际 values
和 def
的 Scala 控制台输出之间的差异。现在,如果我尝试将 prodA1
用作 val
的 value
,我将收到以下错误。
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
Scala 告诉您可以使用 _
显式地将 method
转换为 function
。让我们试试看。
scala> val x = prodA1 _
// x: (Int, Int) => Int = $$Lambda77/293669143@13278a41
现在 x
是类型 (Int, Int) => Int
的 function
。
此外,第一行 Unapplied methods are only converted to functions when a function type is expected.
告诉您实际发生的情况。
因为 prodC1
需要 return 类型 (Int, Int) => Int
的 function
而你提供了 prodA1
,Scala 使用 eta-expansion
自动将你的 method
转换为 function
.
经过反复试验和研究我们的教科书后,我得到了以下功能,我可以想出一个解决方案。
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
}
如果我不把它放在那里,我会得到类型不匹配,有人可以 elaborate/explain 这条线的要求吗?
您的函数需要 return (Int, Int) => Int 的一个实例。
def prodA1(a : Int, b : Int) : Int =
if(a > b) 1 else f(a) * prodA1(a+1, b)
创建一个 (Int, Int) => Int
类型的函数,名称为 prodA1,但 return 类型的 定义 内部函数不会创建任何实例,因此return 函数的类型是 Unit
.
因此您需要 return 具有正确类型的 prodA1
..
我们来看看你的 return 类型。
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
}
你的return类型是
(Int, Int) => Int
这是 Function2[Int, Int, Int]
其中第一个参数是第一个参数的类型,第二个参数是第二个参数的类型,最后一个是 return 参数的类型
return 实例需要是一个函数
prodA1 符合此类型,意味着它可以被 returned。
所以你需要知道很多事情才能真正理解这个问题的答案。
在 Scala 中,任何 def
都是一个 method
,它只不过是一些 object
的成员之一。 methods
不是 Scala 中的第一个 class 成员,这也意味着 methods
不能独立存在。
在 Scala 中,任何东西的 value
都需要是 expression
。这意味着 def
的 RHS 需要像 def abc = some-expression
这样的表达式。表达式的例子有1
、1 + 1
、"xyz"
、anotherMethodCallWhichWillReturnAnExpression()
等
并且像 def abc = xxxxxx
这样的东西在 Scala 语言定义中不是 expression
。因此你不能这样做,
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
添加额外的行时,您是在告诉 Scala return 您刚刚定义的这个 prodA1
。但请记住 prodA1
只是一个 method
,因此不能单独存在,因此实际上不能被 returned。
但是 functions
是 Scala 中的第一个 class 成员(表示为各种 FunctionX
classes 之一的实例)因此可以是 returned.
在这种情况下,Scala 会智能地将此 method
提升为类型 (Int, Int) => Int
的 function
。这称为 eta 扩展。
更详细地了解事物。您可以打开 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
请注意实际 values
和 def
的 Scala 控制台输出之间的差异。现在,如果我尝试将 prodA1
用作 val
的 value
,我将收到以下错误。
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
Scala 告诉您可以使用 _
显式地将 method
转换为 function
。让我们试试看。
scala> val x = prodA1 _
// x: (Int, Int) => Int = $$Lambda77/293669143@13278a41
现在 x
是类型 (Int, Int) => Int
的 function
。
此外,第一行 Unapplied methods are only converted to functions when a function type is expected.
告诉您实际发生的情况。
因为 prodC1
需要 return 类型 (Int, Int) => Int
的 function
而你提供了 prodA1
,Scala 使用 eta-expansion
自动将你的 method
转换为 function
.