2015年6月7日日曜日

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

Exercise 6.10 unit,map2,flatMap,sequenceの5つの関数を一般化せよ。

case class State[S, +A](run: S => (A, S)) {

  def flatMap[B](f: A => State[S, B]): State[S, B] = State(s=> {
   val (a,st)=run(s)
   f(a)(st)
  })
 //  runという関数は、S=>(A,S)なので、run(s)により(a,st)を返す
 //f:A=>State[S,B]だから f(a)はState[S,B]すなわちS=>(A,S)という関数であり、引数は今の場合st:S
//をもってくるとよい。したがってf(a)(st)

 def map[B](f: A => B): State[S, B] =
  flatMap(a=> unit(f(a)) )

 def map2[B,C](sb: State[S, B])(f: (A, B) => C): State[S, C] =
  flatMap(a =>  sb.map(b =>f(a,b)))
//State[S,C]  S=>(C,S)という関数が返値  b=>f(a,b)つまりb=>cをmapに適用する
// と State[S,B]がState[S,C]に変換される  flatMap(f:A=>State[S,C]):State[S,C]という型になっている

}

object State {

  def unit[S, A](a: A): State[S, A] =
    State(s => (a, s))

  def sequenceViaFoldRight[S,A](sas: List[State[S, A]]): State[S, List[A]] =
    sas.foldRight(unit[S, List[A]](List()))((f, acc) => f.map2(acc)(_ :: _))
//ここで、folrRightを復習してみた。
//def foldRight[A,B](as:List[A],z:B)(f:(A,B)=>B):Bだった。
//  (f, acc) => map2(f, acc)(_ :: _) では
// f.map2(acc)(_::_)が f:State[S,A]とacc:State[S,List[A]]を結合して、新たに State[S,List[A]]を返す
 //fにはsas:List[State[S,A]]から  State[S,A]をひとつずつ切り取ってくる感じ?けっこう難しい。

}

case classとobjectに分けて実装しているが、その理由など、基本的なことがまだよくわかってない。

0 件のコメント:

コメントを投稿