Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在Scala中,函数类型需要在单独的参数组中传递到函数中_Scala_Functional Programming - Fatal编程技术网

为什么在Scala中,函数类型需要在单独的参数组中传递到函数中

为什么在Scala中,函数类型需要在单独的参数组中传递到函数中,scala,functional-programming,Scala,Functional Programming,我是scala新手,我用两种方法编写了相同的代码。但我有点混淆了两种方法。在第二种方法中,参数类型f是自动派生的,但在类型1中,scala编译器不能这样做。我只是想了解这背后的想法 Type1:给出编译错误 def rightFold[A,B](xs:List[A],z:B,f:(A,B) => B ): B = xs match { case Nil => z case Cons(x,xs) => f(x,rightFold(xs,z,f)) }

我是scala新手,我用两种方法编写了相同的代码。但我有点混淆了两种方法。在第二种方法中,参数类型f是自动派生的,但在类型1中,scala编译器不能这样做。我只是想了解这背后的想法

Type1:给出编译错误

def rightFold[A,B](xs:List[A],z:B,f:(A,B) => B ): B = xs match {

    case Nil => z
    case Cons(x,xs) => f(x,rightFold(xs,z,f))
  }

  def sum1(l:List[Int]) =  rightFold(l,0.0,_ + _)
类型2:工作正常

  def rightFold[A,B](xs:List[A],z:B)(f:(A,B) => B ): B = xs match {

    case Nil => z
    case Cons(x,xs) => f(x,rightFold(xs,z)(f))
  }

  def sum1(l:List[Int]) =  rightFold(l,0.0)(_ + _)

这与函数类型需要在单独的一组参数中传递(currying)无关。问题在于您在Scala还不知道的类型上使用
+

在执行函数时,编译器可以推断前两个参数的类型为
List[Int]
Double
。这允许解析
+
,因为它知道两侧的类型是
Int
Dobule


现在,为什么编译器不能对单参数列表执行同样的操作呢?事实就是这样,类型信息在参数列表中是不可用的。

如果您传入
(a:Int,b:Double)=>(a+b))
而不是传入
,那么类型1可以工作。对函数进行curry处理可以使用下划线语法,因为在尝试并传递加法函数时,scala编译器已经推断出A和B是什么类型。

类型推断通过参数列表从左向右流动。换句话说,左参数列表中的类型信息在右参数列表中可用,但同一列表中的参数类型是独立推断的。

对于单个列表,
A
的推断类型取决于
xs
f
的类型。但是对于这两个参数列表,它只取决于
xs
类型。

Scala中需要记住的一个粗略准则是:类型推断并不完美,而且在使用时往往效果更好。区别不在于是否使用
,而在于是否给出显式类型:
(:Int)+(:Double)
在第一种情况下有效,
(a,b)=>a+b
在第二种情况下有效。@Mittag是有道理的。好吧,显然不是,否则你(和无数被咬过的人)就不会问这个问题;-)但事实就是这样。Haskell说,与之相比,Scala的类型推断是有限的。首先,Scala有子类型,这使类型推断变得非常复杂。另外,Scala维护人员对任何可能危害良好、有用的编译错误都非常敏感。