
Copyright © Cay S. Horstmann 2015
switch statement:
sign = ch match {
case '+' => 1
case '-' => -1
case _ => 0
}if.break.ch match {
case '+' => sign = 1
case '-' => sign = -1
case _ if Character.isDigit(ch) => digit = Character.digit(ch, 10)
case _ => sign = 0
}
case var assigns the match expression to the variable:
str(i) match {
case '+' => sign = 1
case '-' => sign = -1
case ch if Character.isDigit(ch) => digit = Character.digit(ch, 10)
}import scala.math._
x match {
case Pi => ...
...
}`...`:
import java.io.File._
str match {
case `pathSeparator` => ...
...
}
case var: Type matches if var has the given type:
obj match {
case x: Int => x
case s: String => Integer.parseInt(s)
case _: BigInt => Int.MaxValue
case _ => 0
}
var.isInstanceOf[Type]obj match {
case BigInt => -1 // Matches the BigInt object of type Class
..
}
case syntax:
try {
...
} catch {
case e: IOException => println("Caught " + e)
}try {
...
} catch {
case _: Throwable => println("Oh noes!")
}pair match {
case (0, _) => "0 ..."
case (y, 0) => y + " 0"
case _ => "neither is 0"
}arr match {
case Array(0) => "0"
case Array(x, y) => x + " " + y
case Array(0, _*) => "0 ..."
case _ => "something else"
}case clause:
val (uppercase, lowercase) = "Hello, World".partition(Character.isUpperCase(_)) // partition returns a pair val Array(first, second, _*) = arr
for expressions:
for ((key, value) <- map) // a map is a sequence of pairs println(key + "->" + value)
_*:
val Array(first, second, rest @ _*) = arr
abstract class Amount case class Dollar(value: Double) extends Amount case class Currency(value: Double, unit: String) extends Amount case object Nothing extends Amount
amt match {
case Dollar(v) => "$" + v
case Currency(_, u) => "Oh noes, I got " + u
case Nothing => ""
}val:
case class Currency(value: Double, unit: String) extends Amount
apply factory method:
Currency(1000, "EUR")
toString, equals, hashCode, unapply, and copy are generated.unapply makes extractors work.copy lets you copy values:
val amt = Currency(1000, "EUR") val price = amt.copy() val price2 = amt.copy(unit = "CHF")
Option[T] is a safe alternative to providing a value of type T or null.Some[T] that wraps a value.None that indicates that there is no value.Map[K, V].get returns an Option[V], either Some(v) or
None.val scores = Map("Alice" -> 1, "Bob" -> 2)
scores.get("Alice") match {
case Some(score) => println(score)
case None => println("No score")
}abstract class Expr case class Num(value: Int) extends Expr case class Sum(left: Expr, right: Expr) extends Expr case class Product(left: Expr, right: Expr) extends Expr
val e = Product(Num(3), Sum(Num(4), Num(5)))
def eval(e: Expr): Int = e match {
case Num(v) => v
case Sum(l, r) => eval(l) + eval(r)
case Product(l, r) => eval(l) * eval(r)
}abstract class Expr {
def eval: Int
}
class Sum(val left: Expr, val right: Expr) extends Expr {
def eval: Int = left.eval + right.eval
}

swap that receives a pair of integers and returns the pair with the components swapped.swap that receives an Array[Int] and returns the array with the first two elements swapped, provided the length is at least two.abstract class Item case class Article(description: String, price: Double) extends Item case class Bundle(description: String, discount: Double, items: Item*) extends ItemDeclare an
Article: the book “Scala for the Impatient” for $39.95:
val book = ...
val gift = ...
price(it: Item): Double that computes the price of an item. Use pattern matching. Start with filling in the case for Article. What is your code?price(book)? price(gift)?Bundle case to price. The hard part is to match the varargs. Use case Bundle(_, disc, its @ _*). You want to recursively compute the sum of the prices of the items (Hint: map, sum), and subtract the discount.val special = Bundle("Father's day special", 20.0,
Article("Scala for the Impatient", 39.95),
Bundle("Anchor Distillery Sampler", 10.0,
Article("Old Potrero Straight Rye Whiskey", 79.95),
Article("Junípero Gin", 32.95)))
Write a one-line assigment that extracts the description and price of the first article:
val ...(descr, price)... = special
Option TypeOption type for Double values. Provide classes DoubleOption, SomeDouble, and NoDouble. What are they?inv that maps x into its inverse (1 / x), returning a DoubleOption. Return NoDouble when x is zero. What is your function? What happens when you call inv(2)? inv(0)?Double => DoubleOption, yielding another function of the same type. The composition should yield NoDouble if either function does. For example, with
def f(x: Double) = if (x <= 1) SomeDouble(sqrt(1 - x)) else NoDouble val h = compose(inv, f) // inv(f(x)) when definedthe result of
h(1) and h(2) are NoDouble, but h(0) is SomeDouble(1).isEmpty that returns true for NoDouble and false for SomeDouble. Use pattern matching.get that returns the value wrapped in SomeDouble and throws a NoSuchElementException if there is no value. Use pattern matching.DoubleOption and override them in SomeDouble and NoDouble.