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 件のコメント:
コメントを投稿