Recap: Functions and Pattern Matching
Case class
Representation of JSON
abstract class JSON
object JSON {
case class Seq(elems: List[JSON]) extends JSON
case class Obj(props: Map[String, JSON]) extends JSON
case class Num(num: Double) extends JSON
case class Str(str: String) extends JSON
case class Bool(b: Boolean) extends JSON
case object Null extends JSON
}
The previous object
can be written in enum
.
enum JSON {
case Seq(elems: List[JSON])
case Obj(props: Map[String, JSON])
case Num(num: Double)
case Str(str: String)
case Bool(b: Boolean)
case Null
}
Pattern matching
The string representation of JSON data.
def show(json: JSON): String = json match {
case JSON.Seq(elems) => {
elems.map(show).mkString("[", ",", "]")
}
case JSON.Obj(props) => {
props.map((k, v) => s"\"${k}\": ${show(v)}")
.mkString("{", ",", "}")
}
case JSON.Num(num) => num.mkString
case JSON.Str(str) => s"\"${str}\""
case JSON.Bool(b) => b.toString
case JSON.Null => "null"
}
Collections
Iterable
/ | |
Seq Set Map
/
List
All the collections shares some common functions.
The core functions are:
-
map
extension [T](xs: List[T]) def map(U)(f: T => U): List[U] = xs match { case Nil => Nil case head :: tails => f(head) :: map(tails) }
-
flatMap
extension [T](xs: List[T]) def flatMap(U)(f: T => List[U]): List[U] = xs match { case Nil => Nil case head :: tails => f(head) ++ flatMap(tails) }
xs.flatmap(f) = xs.map(f).flatten
-
filter
and the reduce functions:
foldLeft
foldRight
For-comprehension
It simplifies the combinations of core method, map
, flatMap
, filter
.
Instead of:
(1 until n)
.flatMap(i => (1 until i)
.filter(j => isPrime(i + j))
.map(j => (i, j)))
We can write:
for {
i <- 1 until n
j <- 1 until i
if isPrime(i + j)
} yield (i, j)
What's more, we can apply pattern matching in for-comprehension.
def props(x: JSON): List[(String, JSON)] = x match {
case JSON.Obj(props) => props.toList
case _ => Nil
}
// get all french phone numbers in the json.
for {
// If the prop name is "phoneNumber" and its value is a JSON.Seq, get it
case ("phoneNumber", JSON.Seq(numberInfos)) <- props(json)
numberInfo <- numberInfos
// If the prop name is "number" and its value is a JSON.Number, get it
case ("number", JSON.Number(number)) <- props(numberInfo)
if number.startWith("33")
} yield number