Scala 什么';concat中foldRight和foldLeft的区别是什么
为什么我不能在以下代码中使用“左折”:Scala 什么';concat中foldRight和foldLeft的区别是什么,scala,Scala,为什么我不能在以下代码中使用“左折”: def concatList[T](xs: List[T],ys:List[T]): List[T]= (xs foldLeft ys)(_::_) 事实上,我很难理解foldRight和foldLeft之间的区别,有没有任何例子来说明真正的区别 谢谢。好吧,你可以 scala> def concatList[T](xs: List[T],ys:List[T]) = (xs foldLeft ys)( (a, b) =
def concatList[T](xs: List[T],ys:List[T]): List[T]=
(xs foldLeft ys)(_::_)
事实上,我很难理解foldRight和foldLeft之间的区别,有没有任何例子来说明真正的区别
谢谢。好吧,你可以
scala> def concatList[T](xs: List[T],ys:List[T]) =
(xs foldLeft ys)( (a, b) => b :: a )
concatList: [T](xs: List[T], ys: List[T])List[T]
scala> concatList(List(1,2,3), List(6,7,8))
res0: List[Int] = List(3, 2, 1, 6, 7, 8)
这是你期待的结果吗?我不这么认为
首先,让我们看一下褶皱的签名和:
(只是为了说明目的进行了简化,但非常适合我们的情况):
现在,在foldLeft wexs.foldLeft(ys)
中应用一个参数列表,并统一来自foldLeft示例调用的签名的类型:
List[T]:List[Int],因此应用于foldLeft签名的T:Int和R:List[Int]给出
foldLeft[List[Int]](r:List[Int])( f:(List[Int],Int) => List[Int] )
现在,对于::
的用法,a::b
编译为b.:(a)
,Scala通常将其称为一种正确的关联方法。这是以:
结尾的方法的特殊语法,在定义列表时非常方便:1::2::Nil
就像编写Nil:::(2)。:(1)
继续我们对foldLeft
的实例化,我们需要传递的函数必须如下所示:(List[Int],Int)=>List[Int]
。考虑<代码>(a,b)=a::b,如果我们将其与我们的代码类型> f < /代码> GET:
a:List[Int]和b:Int,将其与a2::b2
,a2:Int,b2:List[Int]的签名进行比较。为了进行编译,a和a2以及b和b2必须具有相同的类型。他们没有
注意,在我的示例中,我反转了参数,使a匹配b2的类型,b匹配a2的类型
我将提供另一个编译版本:
def concatList[T](xs: List[T],ys:List[T]) = (xs foldLeft ys)( _.::(_) )
简而言之,请看foldRight签名
def foldRight[R](r:R)(f: (T,R) => R):R
参数已经反转,因此使f=\u::\ u
为我们提供了正确的类型
哇,这是关于类型推断的很多解释,我很准时,但我仍然需要解释一下左右折叠的含义之间的差异。现在,我们来看看这两种想象:
注意,foldl和foldr的参数是反向的,它首先将函数和它们作为初始参数,r
在签名中,而不是:
用于列表构造,它只使用:
。两个非常小的细节。好吧,你可以
scala> def concatList[T](xs: List[T],ys:List[T]) =
(xs foldLeft ys)( (a, b) => b :: a )
concatList: [T](xs: List[T], ys: List[T])List[T]
scala> concatList(List(1,2,3), List(6,7,8))
res0: List[Int] = List(3, 2, 1, 6, 7, 8)
这是你期待的结果吗?我不这么认为
首先,让我们看一下褶皱的签名和:
(只是为了说明目的进行了简化,但非常适合我们的情况):
现在,在foldLeft wexs.foldLeft(ys)
中应用一个参数列表,并统一来自foldLeft示例调用的签名的类型:
List[T]:List[Int],因此应用于foldLeft签名的T:Int和R:List[Int]给出
foldLeft[List[Int]](r:List[Int])( f:(List[Int],Int) => List[Int] )
现在,对于::
的用法,a::b
编译为b.:(a)
,Scala通常将其称为一种正确的关联方法。这是以:
结尾的方法的特殊语法,在定义列表时非常方便:1::2::Nil
就像编写Nil:::(2)。:(1)
继续我们对foldLeft
的实例化,我们需要传递的函数必须如下所示:(List[Int],Int)=>List[Int]
。考虑<代码>(a,b)=a::b,如果我们将其与我们的代码类型> f < /代码> GET:
a:List[Int]和b:Int,将其与a2::b2
,a2:Int,b2:List[Int]的签名进行比较。为了进行编译,a和a2以及b和b2必须具有相同的类型。他们没有
注意,在我的示例中,我反转了参数,使a匹配b2的类型,b匹配a2的类型
我将提供另一个编译版本:
def concatList[T](xs: List[T],ys:List[T]) = (xs foldLeft ys)( _.::(_) )
简而言之,请看foldRight签名
def foldRight[R](r:R)(f: (T,R) => R):R
参数已经反转,因此使f=\u::\ u
为我们提供了正确的类型
哇,这是关于类型推断的很多解释,我很准时,但我仍然需要解释一下左右折叠的含义之间的差异。现在,我们来看看这两种想象:
注意,foldl和foldr的参数是反向的,它首先将函数和它们作为初始参数,
r
在签名中,而不是:
用于列表构造,它只使用:
。两个非常小的细节。一个从左到右,另一个从右到左。一个从左到右,另一个从右到左。