2015年6月14日日曜日

scala関数型デザイン&プログラミング P149~151

Exercise7.11 choiceNを実装し、choiceNをベースにchoiceを実装せよ.
def choiceN[A](n:Par[Int])(choices:List[Par[A]]):Par[A]=
 es =>  {
    val ind = run(es)(n).get
    run(es)(choices(ind))
  }
run(es)(n).getで ind:Intを返している。choices(ind)はind番目のListの要素であるPar[A]を表す。
(chices.apply(ind)の省略形らしい)

def choice[A](cond:Par[Boolean])(t:Par[A],f:Par[A]):Par[A]=
 choiceN(map(cond)(b => if (b) 0 else 1))(List(t, f))

Exercise7.12 リストの代わりにそれらのMapを使った場合はどうなるか。
def choiceMap[K,V](key: Par[K])(choices: Map[K,Par[V]]): Par[V] =
  es => {
    val k = run(es)(key).get
    run(es)(choices(k))
  }

Exercise7.13 新しいプリミティブchooserを実装し、これを使ってchoiceとchoiceNを実装せよ。
def chooser[A,B](p: Par[A])(choices: A => Par[B]): Par[B] =
  es => {
    val k = run(es)(p).get
    run(es)(choices(k))
  }
これが、じつはflatMapであるという説明のようです。
def flatMap[A,B](p: Par[A])(choices: A => Par[B]): Par[B] =
  es => {
    val k = run(es)(p).get
    run(es)(choices(k))
  }
def choiceViaFlatMap[A](p: Par[Boolean])(f: Par[A], t: Par[A]): Par[A] =
  flatMap(p)(b => if (b) t else f)
def choiceNViaFlatMap[A](p: Par[Int])(choices: List[Par[A]]): Par[A] =
  flatMap(p)(i => choices(i))

Exercise7.14 joinを実装せよ。joinを使ってflatMapを実装する方法はわかるか。またflatMapを使ってjoinを実装することは可能か。
def join[A](a: Par[Par[A]]): Par[A] =
  es => run(es)(run(es)(a).get())

def joinViaFlatMap[A](a: Par[Par[A]]): Par[A] =
  flatMap(a)(x => x)
def flatMapViaJoin[A,B](p: Par[A])(f: A => Par[B]): Par[B] =
  join(map(p)(f))
最後のjoin(map(p)(f))は、型をたどれば矛盾ない感じはするが、いまいちすっきり理解できてない

0 件のコメント:

コメントを投稿