Scala Curried类型不匹配

时间:2018-11-12 13:23:07

标签: 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 
}

如果我不认为类型不匹配,有人可以详细说明/解释此行的要求吗?

3 个答案:

答案 0 :(得分:5)

因此,要真正理解答案,您需要了解很多事情。

在Scala中,任何def都是method,仅是某些object的成员之一。 methods不是Scala的一等会员,这也意味着methods不能单独存在。

在Scala中,任何事物的value必须是expression。意味着def的RHS需要像def abc = some-expression这样的表达式。表达式的示例是11 + 1"xyz"anotherMethodCallWhichWillReturnAnExpression()等。

在Scala语言定义中,类似def abc = xxxxxx之类的不是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返回刚才定义的prodA1。但是请记住,prodA1只是一个method,因此不能单独存在,因此不能实际返回。

但是functions是Scala中的一等成员(表示为各种FunctionX类之一的实例),因此可以返回。

在这种情况下,Scala将智能地将此method提升为function类型的(Int, Int) => Int。这称为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

注意实际valuesdef的Scala控制台输出之间的差异。现在,如果我尝试将prodA1用作value的{​​{1}},则会出现以下错误。

val

Scala告诉您可以使用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 method显式转换为function。让我们尝试一下。

_

现在scala> val x = prodA1 _ // x: (Int, Int) => Int = $$Lambda$1077/293669143@13278a41 x类型的function

此外,第一行(Int, Int) => Int告诉您案件中实际发生的情况。

由于预期Unapplied methods are only converted to functions when a function type is expected.返回类型为prodC1的{​​{1}},并且您提供了function,所以Scala使用(Int, Int) => Int自动转换了{{1} }到prodA1

答案 1 :(得分:0)

您的函数需要返回(Int,Int)=> Int的实例。

  def prodA1(a : Int, b : Int) : Int =
    if(a > b) 1 else f(a) * prodA1(a+1, b)

创建一个名称为prodA1的类型为(Int, Int) => Int的函数,但是定义的返回类型内部函数不会创建任何实例,因此该函数的返回类型为{{1 }}。

因此,您需要返回类型正确的Unit

答案 2 :(得分:0)

让我们看看您的退货类型。

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 
}

您的退货类型为

 (Int, Int) => Int 

这是Function2[Int, Int, Int]的斯卡拉糖

其中第一个参数是第一个参数的类型,第二个参数是第二个参数的类型,最后一个是返回参数的类型

返回实例必须是一个函数

prodA1符合此类型,这意味着可以将其返回。