//右折叠 从最右端开始真正的计算
def foldRight[A, B](as: List[A], z: B)(f: (A, B) => B): B = as match {
case Nil => z
case Cons(t, h) => f(t, foldRight(h, z)(f))
case Cons(t, h) => foldLeft(h, f(t, z))((x, y) => f(y, x)) //使用foldLeft 来实现 foldRight
}
//使用右折叠计算链表长度
def length[A](l: List[A]): Int = l match {
case Nil => 0
case Cons(_, t) => foldRight(t, 1)((_, y) => y + 1)
//参数对应 这里的下划线对应 t中的某一个元素 y对应1 这里的1是起始数据 后面会跟这进行变化
}
def length2[A](l: List[A]): Int =foldRight(l,0)((_,y)=>1+y)
def length3[A](l: List[A]): Int =foldRight(l,0)((_,y)=>1+0)
//这个方法 直接返回 因为在运行第一次后 可以直接进行f函数的表达式的运算 1+0 运算式里没有需要继续解决的 表达式 所以直接返回结果
//因而不会进行后续的迭代 f(t, foldRight(h, z)(f)) 到第一步 就直接返回1+0了 没有后续的运算 进行递归的话 需要运算的表达式中还需要有
//待处理的 运算式 而不是参数
- 递归的发生条件是 把运算过程 带到自己要进行具体的执行过程中 如果执行过程中 不存在了需要解决的运算过程 那么直接返回结果 而不管参数如何
def length3[A](l: List[A]): Int =foldRight(l,0)((_,y)=>1+0)
这行代码 在执行 第一次的时候 如下
f(t, foldRight(h, z)(f))=f( _ ,foldRight(_,0)f)=1+0
- 如上 后面的执行过程中 已经没有要处理的运算过程 因而会直接返回结果 1
需要变成下面这样
f(t, foldRight(h, z)(f))=f( _ ,foldRight(_,0)f)=1+foldRight(_,0)
- 这样 才会接着进行下去
- 所以
1+0
要变为1+y
才行