我搞不懂这意味着什么。我理解赛跑,但我似乎看不清所有的代码。
def foldLeft [A,B](xs:List[A], e:B, f:(B,A)=>B): B发布于 2022-10-01 06:41:56
只是几个建议。
顺便说一句,没有人跑进来。
def foldLeft[A,B](xs: List[A], e: B, f: (B, A) => B): B如果有f: B => A => B、def foldLeft[A, B](xs: List[A])(e: B)(f: (B, A) => B): B或def foldLeft[A, B]: List[A] => B => ((B, A) => B) => B等,那么foldLeft就是高阶函数 (方法),即接受另一个函数(f)的函数。
foldRight/foldLeft的wiki文章特别是看看我们是如何解构一个列表的,并从我们执行计算的目的出发:


foldRight/foldLeft看作是定义递归 (而不是模式匹配列表和进行递归调用)的一种简单方法。让我们考虑一个例子。让我们进行一些递归。例如,让我们有一个包装类
case class Value[A](value: A)让我们将一个Value[A]列表转换为一个值,将一个A列表(即List[Value[A]] )包装到Value[List[A]]中。例如,我们希望将List(Value(1), Value(2), Value(3))转换为Value(List(1, 2, 3)) (我实际上需要这样的函数最近)。当然,我们可以用.map来完成这个任务,但是让我们假设我们不知道map (我们可以进行映射,因为map可以通过foldRight/foldLeft表示)。
我们可以通过两种方式递归地完成这个任务(至少)。简单递归
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] = values match {
case Nil => Value(Nil)
case v :: vs => Value(v.value :: valuesToValue(vs).value)
}或带有辅助函数和累加器的尾递归
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] = {
@tailrec
def loop(values: List[Value[A]], acc: Value[List[A]]): Value[List[A]] = values match {
case Nil => Value(acc.value.reverse)
case v :: vs => loop(vs, Value(v.value :: acc.value))
}
loop(values, Value(Nil))
}非常简单。只是包装-拆开。
valuesToValue的两个递归实现都可以(自动)用foldRight/foldLeft重写。前一个递归可以用foldRight重写.后一种递归(尾一)可以用foldLeft重写.
让我们用foldRight重写第一次递归。分支case Nil => ...的值成为foldRight的第一个参数。如果将递归调用的结果替换为一个新的变量case v :: vs => ...,则分支valuesToValue(vs)的值将成为foldRight的第二个参数,因此在foldRight的第二个参数中,我们将有一个v: Value[A]和res: Value[List[A]]函数。
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] =
values.foldRight( Value(Nil: List[A]) ){
(v, res) => Value(v.value :: res.value)
}让我们用foldLeft重写第二次递归(尾一)。
首先,让我们回顾一下,由于运行,我们可以将助手loop理解为Value[List[A]] => Value[List[A]]中的一个单参数函数。
def loop(values: List[Value[A]]): Value[List[A]] => Value[List[A]] = values match {
case Nil => acc => Value(acc.value.reverse)
case v :: vs => acc => loop(vs)(Value(v.value :: acc.value))
}现在,来自分支case Nil => ...的值成为foldLeft的第一个参数。如果我们用一个新变量(函数)替换递归调用case v :: vs => ...的结果,则分支loop(vs)(_)的值将成为foldLeft的第二个参数。
def valuesToValue[A](values: List[Value[A]]): Value[List[A]] = {
def loop(values: List[Value[A]]): Value[List[A]] => Value[List[A]] =
values.foldRight[Value[List[A]] => Value[List[A]]](
acc => Value(acc.value.reverse)
)(
(v, res) => acc => res(Value(v.value :: acc.value))
)
loop(values)(Value(Nil))
}因此,粗略地说,来自分支case Nil => ...和case v :: vs => ...的值将成为foldRight/foldLeft的参数,这取决于我们是用简单递归计算还是用累加器计算尾递归。
发布于 2022-10-01 11:43:31
让我们深入研究这个方法签名:
foldLeft[A,B](xs: List[A], e: B, f: (B, A) => B): BfoldLeft是一种具有三个参数的方法A和B是类型参数xs是该方法的第一个参数,属于List[A]类型。e是第二个参数,类型为B。f是第三个参数,类型为(B, A) => B 。(B, A) => B表示一个函数,它分别接受B和A类型的两个参数,并返回一个BB是该方法的返回类型。https://stackoverflow.com/questions/73915799
复制相似问题