-
Notifications
You must be signed in to change notification settings - Fork 0
/
ch4.scala
78 lines (61 loc) · 2.29 KB
/
ch4.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import scala.{Option => _, Some => _, Either => _, _} // hide std library `Option`, `Some` and `Either`, since we are writing our own in this chapter
sealed trait Option[+A] {
def map[B](f: A => B): Option[B] = this match {
case Some(n) => Some(f(n))
case None => None
}
def getOrElse[B>:A](default: => B): B = this match {
case None => default
case Some(n) => n
}
def flatMap[B](f: A => Option[B]): Option[B] = {
this.map(f) getOrElse None
}
def orElse[B>:A](ob: => Option[B]): Option[B] = this match {
case None => ob
case s => s
}
def filter(f: A => Boolean): Option[A] = this match {
case Some(a) if(f(a)) => Some(a)
case _ => None
}
}
case class Some[+A](get: A) extends Option[A]
case object None extends Option[Nothing]
object Option {
def failingFn(i: Int): Int = {
val y: Int = throw new Exception("fail!") // `val y: Int = ...` declares `y` as having type `Int`, and sets it equal to the right hand side of the `=`.
try {
val x = 42 + 5
x + y
}
catch { case e: Exception => 43 } // A `catch` block is just a pattern matching block like the ones we've seen. `case e: Exception` is a pattern that matches any `Exception`, and it binds this value to the identifier `e`. The match returns the value 43.
}
def failingFn2(i: Int): Int = {
try {
val x = 42 + 5
x + ((throw new Exception("fail!")): Int) // A thrown Exception can be given any type; here we're annotating it with the type `Int`
}
catch { case e: Exception => 43 }
}
def mean(xs: Seq[Double]): Option[Double] =
if (xs.isEmpty) None
else Some(xs.sum / xs.length)
def variance(xs: Seq[Double]): Option[Double] = ???
def map2[A,B,C](a: Option[A], b: Option[B])(f: (A, B) => C): Option[C] = ???
def sequence[A](a: List[Option[A]]): Option[List[A]] = ???
def traverse[A, B](a: List[A])(f: A => Option[B]): Option[List[B]] = ???
}
object Main extends App {
val n = None
val si = Some(123)
val ss = Some("abc")
println(ss.map(_ + "def"))
println(si.getOrElse(-1))
println(n.getOrElse("you can't get a none, so here I am"))
println(si.orElse(Some(-1)))
println(n.orElse(Some("or else result, because I was performed on a None")))
println(si.filter(_<200))
println(si.filter(_<0))
println(si.flatMap(s => Some(s*2)))
}