2015年5月25日月曜日

scala関数型デザイン&プログラミング P88 89

Exercise 5.4 Streamの要素のうち、指定された述語とマッチするものをすべてチェックするforAllを実装せよ。
def forAll(p:A=>Boolean):Boolean =
 foldRight(true)((a,b)=p(a)&&b)


Exercise 5.5 foldRightを使ってtakeWhileを実装せよ
 def takeWhile3(p:A=>Boolean):Stream[A] =
  foldRight(empty[A])((a,st)=>if p(a) cons(a,st) else st)
最後をstにしたが、解答はemptyだった。そうしないと、いったんfalseになっても、trueになると
前のStreamに追加されていく。(あとで出てくるfilterだとそれでいいが)

Exercise 5.6 foldRigthを使ってheadOptionを実装せよ
  def headOption:Option[A] =
 foldRight2(None:Option[A])( (a,_) =>if (a!=Nil) Some(a) else None )
最初foldRightの引数のNoneにOption[A]をつけなかったところ、エラーがでた。このへんの必要性について、いまいち理解できてない。
解答は
def headOption: Option[A] =
  foldRight(None: Option[A])((h,_) => Some(h))
となっていた。わざわざifはつける必要がないといことだ。hがNilでもNoneとなるようだ。

Exercise 5.7 foldRightを使って、map,filter,append.flatMapを実装せよ

def map[B](f:A=>B):Stream[B] =
 foldRight2(empty[B])( (a,st) => cons(f(a),st)  )

def filter(f: A => Boolean): Stream[A] =
 foldRight2(empty[B])( (a,st) => if (f(a)) cons(a,st) else st)

def append[A](as:Stream[A],bs:Stream[A]):Stream[A]=
 as.foldRight2(bs)((a,b)=>cons(a,b))
としたが、これでは引数を非正格にという条件にあわないので、間違い。
正しくは
 def append[B>:A] (bs: => Stream[B]):Stream[B]=
 foldRight2(bs)((a,b)=>cons(a,b))
ということだった。変位についても考慮して上位のBの型にしないとだめだそうだ。変位の指定ははまだ理解が難しい。

def flatMap[B](f:A=>Stream[B]):Stream[B] =
 foldRight(empty[B])( (a,st)=>cons(f(a).head,st)  ) 
ということは無理だったheadのような使いかたはできない
正解は  foldRight(empty[B])((a,st) => f(a).append(st))
appendを使うことは気づかなかった


0 件のコメント:

コメントを投稿