Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Abstract Data Type

Option

With Option you can eliminate the use of null in Scala. An Option has two values Some or None.

  • None wraps the null pointer
  • Some wraps the value
scala> val optStr = Option("hello")
val optStr: Option[String] = Some(hello)
                                                                                
scala> optStr match 
     | case Some(value) => s"the result is: $value"
     | case None => "there is no result"
     | 
val res5: String = the result is: hello
                                                                                
scala> val optStr = Option(null)
val optStr: Option[Null] = None
                                                                                
scala> optStr match 
     | case Some(value) => s"the result is: $value"
     | case None => "there is no result"
     | 
val res6: String = there is no result
                                            
scala> val map = Map(1 -> "a", 2 -> "b", 3 -> "c")
val map: Map[Int, String] = Map(1 -> a, 2 -> b, 3 -> c)

scala> map(3)
val res0: String = c

scala> map(4)
java.util.NoSuchElementException: key not found: 4
at scala.collection.immutable.Map$Map3.apply(Map.scala:399)
... 40 elided

scala> map.get(3)
val res1: Option[String] = Some(c)

scala> map.get(4)
val res2: Option[String] = None

Try

`Try' wraps an exception.

An Option has two values Some or None.

  • Failure wraps the exception
  • Success wraps the value
 val x = 3 / 0
java.lang.ArithmeticException: / by zero
  ... 40 elided
scala> import scala.util.{Try, Success, Failure}

scala> val x = Try(3 / 0)
val x: scala.util.Try[Int] = Failure(java.lang.ArithmeticException: / by zero)

scala> val x = Try(3 / 1)
val x: scala.util.Try[Int] = Success(3)
scala> x match
    | case Success(value) => s"calculation successful with the value:  $value"
    | case Failure(ex) => s"calculation failure with exception:  $ex"
    |
val res1: String = calculation successful with the value:  3

Either

An Either also wrap two value Right and Left. It is something between the Option and the Try and more general, but less used.

In this example an exception is wrapped inside an Either.
Try would be more natural.

def returnEither(value: String): Either[NumberFormatException, Int] =
    try 
        Right(value.toInt)
    catch 
        case ex: NumberFormatException => Left(ex)
    
def resultEither(value: String) =
  returnEither(value) match
    case Right(value) => s"Right value: $value"
    case Left(ex) => s"Left exception: $ex"
scala> resultEither("12")
val res2: String = Right value: 12

scala> resultEither("ab")
val res3: String = Left exception: java.lang.NumberFormatException: For input string: "ab"

Exercises

Exercise 1

  1. Write a function that returns an Option[String]
  2. Call the function and pattern match on the possible results

Exercise 2

  1. Write a map with the days of the week 1 "monday", 2 :"tuesday", etc
  2. Write a function day that returns the name of the day or an error message
def dayOfTheWeek(day: Int, map: [Int, String]): Option[String] = ???

Exercise 3

Write a vector with the number 1 to 10

val vector = Vector(1,2,3,4,5,6,7,8,9,10)

Write a function indexOf that

  • return the number at the index
  • or an error message when the index is out of bounds.
def indexOf(index: Int, vector: Vector[Int]): Try[Int] = ???

Call the indexOf function and print the result in a pattern match

indexOf(2, vector) match ???

Exercise 4

Do the same as in Exercise 3 but now use 'Either'

def indexOf(index: Int, vector: Vector[Int]): Either[Int] = ???