fp in scala 学习随记(1)

来源:互联网 发布:java中long转换成date 编辑:程序博客网 时间:2024/05/21 19:43

Foldright foldleft
先来看一下foldleft的一个简单定义

@annotation.tailrecdeffoldLeft[A,B](as:List[A],z:B)(f:(B,A)=>B):B = as match{case Nil=> zcase Cons(h,t) =>foldLeft(t,f(z,h))(f)}

尾递归版本foldleft,每次把第一个h与z进行f运算然后递归调用foldleft

Foldright很多情况下不是尾递归的,我们要改写成尾递归形式
使用尾递归的foldleft来实现foldright

def foldRight1[A,B](as: List[A], z: B)(f: (A, B) => B): B = {foldLeft(reverse(as), z)((b, a) => f(a, b))}
def foldRight2[A,B](as: List[A], z: B)(f: (A, B) => B): B = {foldLeft(as, (b: B) => b) ((g, a) => b =>g(f(a, b))) (z)}

第一个里面使用的是通过foldleft来实现的一个reverse函数

defreverse(ns:List[A]):List[A] = {foldLeft(ns,List[A]())((acc,h)=>Cons(h,acc))}

很简单,略过
第二个函数就不是很好懂了,我们来把它拆开
改写一下定义:

def foldRight3[A,B](as: List[A], outerIdent: B)(combiner: (A, B)=> B): B =

我们不需要直接build出 B 的value,因此我们使用了一个函数 BtoB:B=>B fold的过程需要 a:A 和一个函数 g: B=>B.
因此我们有了一个新函数

(b => g(f(a,b))): B=>B.

我们可以把fold过程写成这样:

As.foldLeft(identity _)((g, a) => g compose (b => f(a, b)))(z)

我们来看一下这个语句:对于 as 中的所有元素 a,我们部分施用 b=> f (b,a),这个函数是个B=>B类型的。然后我们将函数复合一下:
(g, a) => b => g(f(a, b)). 最后把这整个的函数应用到z上,就是

 ((g, a)=> b => g(f(a, b))) (z)
0 0
原创粉丝点击