2015年6月2日火曜日

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

Exercise 6.6 以下のシグネチャに基づいてmap2を実施せよ。この関数は、raとrbの2つのアクションと、それらの結果を結合する関数fを受け取り、それらを結合する新しいアクションを返す。
def map2[A,B,C](ra: Rand[A], rb: Rand[B])(f: (A, B) => C): Rand[C] =
 rng => {
  val (a,rng2)=ra(rng)
  val (b,rng3)=rb(rng2)
  (f(a,b),rng3)
 }

Exercise 6.7 2つのRNG遷移の組み合わせが可能であるとしたら、それらのリストを結合することも可能であるはずだ。遷移のListを1つの遷移にまとめるためのsequenceを実装せよ。それを使って、以前記述したints関数を再実装せよ。その際には、標準ライブラリのList.fill(n)(x)関数を使ってxをn回繰り返すリストを作成できる。
解答は
def sequence[A](fs: List[Rand[A]]): Rand[List[A]] =
  fs.foldRight(unit( List[A]() ))  (  (f, acc) => map2(f, acc)(_ :: _)  )
unit(List[A]())は rng=>(List[A](),rng) で Rand[List[A]]
  (f, acc) => map2(f, acc)(_ :: _) では
 map2(f,acc)(_::_)が f:Rand[A]とacc:Rand[List[A]]を結合して、新たに Rand[List[A]]を返す
 fにはfs:List[Rand[A]]から  Rand[A]をひとつずつ切り取ってくる感じだろうか。。
確かに、これは難問

def _ints(count: Int): Rand[List[Int]] =
  sequence(List.fill(count)(int))
 val int:Rand[Int] = _.nextInt で乱数を発生 それをcount回繰り返すリスト(List[Rand[Int]])を作成している。 そして、それをsequenceでRand[List[Int]]に変換している。




0 件のコメント:

コメントを投稿