2015年6月30日火曜日

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

モノイド、モナドの章は、抽象的な内容で難しいといえば難しいのだが、試行錯誤の文章が少ないので、パートⅡの章に比べれば読みやすい。途中の問題への取り組みはあちこち省き、読み進んだ。

結合律の説明がすぐには理解できなかったので、丁寧にたどってみた。
x.flatMap(f).flatMap(g)==x.flatMap(a=>f(a).flatMap(g))の結合律で、xをSome(v)に置き換えると
Some(v).flatMap(f).flatMap(g) == Some(v).flatMap(a=>f(a).flatMap(g))であることを示す。
def flatMap[B](f:A=>Option[B]):Option[B]だから、
左辺のSome(v).flatMap(f)の部分はSome(v)のvに関数fを適用してf(v):Option[B]となる。
右辺のほうは、Some(v)のvに関数a=>f(a).flatMap(g)を適用するので、
v=>f(v).flatMap(g)で、結局f(v).flatMap(g)

Exercise11.7 クライスリ関数composeを実装せよ
def compose[A,B,C](f: A => F[B], g: B => F[C]): A => F[C] =
  a => flatMap(f(a))(g)
f: A => F[B]の部分は、a=>f(a)で、次にg: B => F[C]のところは、flatMapを使うしかない。
( def flatMap(g:B=>F[C]):F[C]とみなして )
f(a).flatMap(g)とも書けるが、flatMap(f(a))(g)ということ。

Exercise 11.9 flatMapの観点からの結合律と、composeの観点からの結合律の式が等価であることを証明せよ。
compose(compose(f, g), h) == compose(f, compose(g, h))

a => flatMap(compose(f, g)(a))(h) == a => flatMap(f(a))(compose(g, h))
a => flatMap((b => flatMap(f(b))(g))(a))(h) == a => flatMap(f(a))(b => flatMap(g(b))(h))
左辺を少し簡単にすると
( b => flatMap(f(b))(g) )(a)は b => flatMap(f(b))(g)にaを適用するということ
だから a=> flatMap(f(a))(g) つまり下記のようになる
a => flatMap(flatMap(f(a))(g))(h) == a => flatMap(f(a))(b => flatMap(g(b))(h))
aを除いて簡単にする。f(a)の代わりにxとすると
flatMap(flatMap(x)(g))(h) == flatMap(x)(b => flatMap(g(b))(h))
文字を置き換えると
flatMap(flatMap(x)(f))(g) == flatMap(x)(a => flatMap(f(a))(g))
ん~ けっこう、ややこしい。

0 件のコメント:

コメントを投稿