2015年5月17日日曜日

scala関数デザイン&プログラミング P53

Exercise3.20 mapと同じ働きをするflatMap関数を記述せよ。
def flatMap[A,B](as:List[A])(f:A=>List[B]):List[B] =
 foldRight(as:List[A],Nil:List[B])( (x,bs)=>concat(List(f(x),bs))  )

 もっと簡単に
 def flatMap[A,B](l: List[A])(f: A => List[B]): List[B] =
  concat(map(l)(f))
  でいいようだ。map(l)(f)はList(List[B])の型になるが、concatによりList[B]になるということのようだ。


Exercise3.21 flatMapを使ってfilterを実装せよ。
 def filter2[A](as:List[A])(f:A=>Boolean):List[A]=
  flatMap(as)((i)=> if (f(i)) List(i) else List() )

Exercise3.22 リスト2つをうけとり、対応する要素どうしを足し合わせて新しいリストを生成する関数を記述せよ
 def plus(as:List[Int],bs:List[Int]):List[Int]=
  (as,bs) match {
   case (Nil,Nil)=>Nil
   case (Cons(x,xs),Nil)=>Cons(x,plus(xs,Nil))
   case (Nil,Cons(y,ys))=>Cons(y,plus(Nil,ys))
   case (Cons(x,xs),Cons(y,ys)) => Cons(x+y,plus(xs,ys))
   }
解答は、どちらも数字がないと足さないとしていたが、ここでは、数字がないときは、0とみなしていちおう計算してみた。

Exercise3.23 3.22で作成した関数を、整数または加算に限定されないように一般化せよ
def zipWith[A](as:List[A],bs:List[A])(f:(A,A)=>A):List[A]=
 (as,bs) match {
   case (_,Nil)=>Nil
   case (Nil,_)=>Nil
   case (Cons(x,xs),Cons(y,ys)) => Cons(f(x,y),zipWith(xs,ys)(f))
   }
正解では、すべての型をAにしていなかった。f:(A,B)=>Cと直す必要あり。

0 件のコメント:

コメントを投稿