2015年5月23日土曜日

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

Exercise 4.32項関数を使いOption型の2つの値を結合する総称関数map2を実装せよ
def map2[A,B,C](a:Option[A],b:Option[B])(f:(A,B)=>C):Option[C] =
 (a,b) match {
  case (Some(aa),Some(bb)) => Some(f(aa,bb))
  case (_,_) =>None
}
と考えたが、Optionは原則flatMapを使ったほうがスマートになるらしい。解答は
def map2a[A,B,C](a: Option[A], b: Option[B])(f: (A, B) => C): Option[C] =
  a flatMap (aa => b map (bb => f(aa, bb)))

def lift[A,B](f:A=>B):Option[A]=>Option[B]=_ map f
を参考にすると
 b map (bb => f(aa,bb))がいわゆるliftを適用したものにあたり bb=>f(aa,bb)がA=>Bにあたる。
Option[B]=>Option[C]という関数にbを適用した結果だから、b map (bb => f(aa,bb)):Option[C]とみなせる。
(ただ、この部分でaaが確定してないから、aaの関数ともみなせる?)
したがって、aa:AからOption[C]への関数がflatMapの引数となっており、
a:Option[A]をmap2aに適用すれば、Option[C]に変換される。
二項関数は、flatMapとmapをうまく組み合わせるとできるということは、わかったが、けっこう、ややこしい。

0 件のコメント:

コメントを投稿