Created
July 21, 2015 02:46
-
-
Save sambaiz/ce476967240831c66792 to your computer and use it in GitHub Desktop.
Scala関数型デザイン&プログラミング4章
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
EXERCISE 4.1 | |
trait Option[+A]{ | |
def map[B](f: A => B): Option[B] | |
def flatMap[B](f: A => Option[B]): Option[B] | |
def getOrElse[B >: A](default: => B): B | |
def orElse[B >: A](ob: => Option[B]): Optino[B] | |
def filter(f: A => Boolean): Option[A] | |
} | |
を実装せよ | |
**/ | |
trait Option[+A]{ | |
def map[B](f: A => B): Option[B] = { | |
this match{ | |
case Some(x) => Some(f(x)) | |
case _ => None | |
} | |
} | |
def flatMap[B](f: A => Option[B]): Option[B] = { | |
this match { | |
case Some(x) => f(x) | |
case _ => None | |
} | |
} | |
def getOrElse[B >: A](default: => B): B = { | |
this match { | |
case Some(x) => x | |
case _ => default | |
} | |
} | |
def orElse[B >: A](ob: => Option[B]): Option[B] = { | |
this match { | |
case Some(x) => Some(x) | |
case _ => ob | |
} | |
} | |
def filter(f: A => Boolean): Option[A] = { | |
this match { | |
case Some(x) if f(x) => Some(x) | |
case _ => None | |
} | |
} | |
} | |
case class Some[+A](get: A) extends Option[A] | |
case object None extends Option[Nothing] | |
object OptionTest{ | |
def main(args: Array[String]): Unit ={ | |
val opt = Some(1) | |
opt.map(a => println(a)) | |
opt.flatMap(a => Some(10)).map(a => println(a)) | |
println(opt.getOrElse(0)) | |
opt.filter(a => a != 1).map(a => println("a is not 1")) | |
opt.filter(a => a == 1).map(a => println("a is 1")) | |
} | |
} | |
/** | |
* EXERCISE 4.2 | |
* flatMapをベースとしてvariance関数を実装せよ | |
*/ | |
object Variance{ | |
// flatMapどう使うの | |
def variance(xs: Seq[Double]): Option[Double] = { | |
if(xs.length != 0){ | |
val m = xs.sum / xs.length | |
Some(xs.map(x => math.pow(x - m, 2)).sum / xs.length) | |
}else{ | |
None | |
} | |
} | |
def main(args: Array[String]): Unit ={ | |
println(variance(Seq(0,1,2))) | |
println(variance(Seq())) | |
} | |
} | |
/** | |
EXERCISE 4.3 | |
2項関数を使ってOption型の2つの値値を結合する総称関数map2を記述せよ | |
どちらかのOption値がNoneの場合は、戻り値もNoneになる | |
**/ | |
object Map2{ | |
def map2[A,B,C](a: Option[A], b: Option[B])(f: (A, B) => C): Option[C] = { | |
/* | |
if(a == None || b == None){ | |
None | |
}else { | |
val va = a match { | |
case Some(x) => x | |
} | |
val vb = b match { | |
case Some(x) => x | |
} | |
Some(f(va, vb)) | |
} | |
*/ | |
// シンプル | |
a. flatMap (aa => | |
b map (bb => | |
f(aa, bb) | |
) | |
) | |
// for内包表記で記述するとこうもかける | |
/* | |
for { | |
aa <- a | |
bb <- b | |
} yield f(aa, bb) | |
*/ | |
} | |
def main(args: Array[String]): Unit ={ | |
println(map2(Some(1), Some(2))((a: Int, b:Int) => a + b)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment