Exercise 6.8
flatMapを実装し、それを使ってnonNegativeLessThanを実装せよ。
def flatmap[A,B](f:Rand[A])(g:A=>Rand[B]):Rand[B] = { rng =>
val (a,rng2)=f(rng)
g(a)(rng2)
}
まず、fはRand[A]の型、つまり rng=>(a,rng2)を表す。したがって、val (a,rng2)=f(rng)となる。
つぎに、g:A=>Rand[B]より g(a)がRand[B]を表す。これにrng2を適用したg(a)(rng2)が返り値
そして、最終的に、flatMapの返り値は、{rng=>g(a)(rng2)}で、これはRand[B]
def nonNegativeLessThan2(n:Int):Rand[Int] =
flatMap(nonNegativeInt)(i=>
val mod=i%n
if (i+(n-1)-mod>=0)
unit(mode)
else
nonNegativeLessThan2(n)
)
flatMapの第1引数は、Rand[A]なので、nonNegativeInt:Rand[Int]という関数でいい。
次に、第2引数は、A=>Rand[B]という型の関数。AはInt、つまり変数iとして、これを引数として
Rand[B]が返り値になるような関数を記述するとよい。
この場合の返り値の計算は (i+(n-1)-mod)がTrueなら、unit(mode)つまり、rngが変化せず、(mode,rng)をそのまま返すような関数。falseならば、リトライする関数となる。
Exercise 6.9 flatMapを使ってmap,map2を再実装せよ。
def _map[A,B](s:Rand[A])(f:A=>B):Rand[B]=
flatMap(s)(a=>unit(f(a))
unitを使えばA=>Rand[B]の部分をうまく表せる
def _map2[A,B,C](ra:Rand[A],rb:Rand[B])(f:(A,B)=>C):Rand[C] =
flatMap(ra)(a => map(rb)(b => f(a, b)))
こちらは解答例。 ra,rbのふたつ同時には変換は無理なので mapを使うとひとつずつできる。
0 件のコメント:
コメントを投稿