fp in scala 第三章11-20

不得不说这一章题量有点狠,接着干吧

11

用foldLeft实现sum,product,length


  def sum3(ns: List[Int]) = foldLeft(ns, 1)(_ + _)
  def product3(ns: List[Double]) = foldLeft(ns, 1.0)(_ * _)
  def length2[A](as: List[A]): Int = foldLeft(as, 1)((acc, _) => acc + 1)

这个主要就是一个初值设置的问题,没啥好说的

12

实现一个逆序功能,输入List(1,2,3),返回List(3,2,1)
思路,这个也是用foldLift进行,foldLift的初值应该是一个空的列表,而xs是列表类型,x是元素类型,则对每个元素实现Cons的逆操作,则实现了逆序

def reverse[A](as: List[A]): List[A] = foldLeft(as, List[A]())((xs, x) => Cons(x, xs))

14

用foldRight实现append

 def append[A](xsa: List[A], xsb: List[A]) = foldRight(xsa, xsb)((x, xs) => Cons(x, xs))

15

拆分列表
实现思路:初始化一个空列表,然后将as的每个元素都append到空列表中即可

 def concatenate[A](as: List[List[A]]) = foldRight(as, Nil: List[A])(append)

16,17,18

这里我看到对每一个元素加1这种需求就想到了实现一个map函数
刚好瞄了一眼下面的题目,18就是实现一个map,所以就先实现的18
map就是对list的每一个元素都执行函数,并转化成另一个list
实现思路也很简洁,如果as是Nil则返回Nil,否则对Cons的第一个元素执行f函数,并作为新的Cons的head,而对tail递归map

  def map[A, B](as: List[A])(f: A => B): List[B] = as match {
    case Nil => Nil
    case Cons(x, xs) => Cons(f(x), map(xs)(f))
  }

那么加一的需求:

def add(xs: List[Int]) = map[Int, Int](xs)(x => x + 1)

Double2String的需求

 def double2String(as: List[Double]) = map(as)(x => x.toString)

19

实现一个Filter,筛选List中的元素
实现思路也很自然,判断as是不是Nil,是Nil则返回Nil,否则如果第一个元素满足f函数,则构造Cons,head为x,尾部递归调用filter,否则尾部调用filter,舍弃头部

  def filter[A](as: List[A])(f: A => Boolean): List[A] = as match {
    case Nil => Nil
    case Cons(x, xs) => if (f(x)) Cons(x, filter(xs)(f)) else filter(xs)(f)
  }

20

实现一个flatMap,flatMap和map主要区别就是将多重嵌套的list进行拆解成一个list
这里就可以用到刚才定义的concatenate对元素进行拆分,由于map(as)(f)之后返回的是每个元素都是list类型,所以再执行一下拆分就可以了
所以代码为

def flatMap[A, B](as: List[A])(f: A => List[B]): List[B] = concatenate(map(as)(f))

你可能感兴趣的:(scala)