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