2015年5月21日木曜日

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

Exercise4.1 trait Optionのmap,flatMap,getOeElse,getElse,filterの関数をOptionで実装せよ。

eclipseでコンパイルしないとうまく実行できなかった。
とりあえず、解答も参考にしながら、次のようなものを考えてみた。

import scala.{Option => _, Either => _, _}

//以下のprintln文で動作を確認してみた
object Main {
   def main(args:Array[String]) = {

       val x:Option[Int]=Some(1)
       val y:Option[String]=None
       println(x)
       println(x.map(i=>i.toDouble))
       println(y.getOrElse(999))
       println(x.flatMap(i=>Some(i.toDouble)))
       println(x.filter(_<2))

    }
}


case class Some[+A](get: A) extends Option[A]
case object None extends Option[Nothing]

sealed trait Option[+A] {
  def map[B](f: A => B): Option[B] = this match {
    case None => None
    case Some(a) => Some(f(a))
  }


//Option値がNoneなら、ディフォルト値だが、Someならその中身
// 引数名: =>引数の型  は、遅延評価(メソッド呼び出す前には評価されない)
  def getOrElse[B>:A](default: => B): B = this match {
   case None => default
   case Some(a) => a
   }
 

  def flatMap[B](f: A => Option[B]): Option[B] =
    map(f).getOrElse(None)

 //二つ目のOptionというのが意味が分からなかったが、要するに引数のことでしょうか?
 //orElse(一つ目のOption,二つ目のOption)とみなしたということ? 一つ目のOption.orElse(二つ目のOption)と考えていたのでよくわからなかった。
 //自分自身はthisとするようだ
    def orElse[B>:A](ob: => Option[B]): Option[B] = this match {
    case None=> ob
    case Some(b) => this
    }
// 解答の
//  def orElse[B>:A](ob: => Option[B]): Option[B] =
//    this map (Some(_)) getOrElse ob
//  という発想はなかなか出てこなかった。Some(_)は、b:B=>Some(b):Option[B] そして
//map(b=>Some(b)でSome(Some(b))になるが
  //getOrElseでまた、Some(b)にもどるということだろうか。ちょっと回りくどい気がしないでもないが。

    def filter(f: A => Boolean): Option[A] = this match {
    case None => None
    case Some(a) => if (f(a)) this else None
    }
}

0 件のコメント:

コメントを投稿