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
- Write a function that returns an Option[String]
- Call the function and pattern match on the possible results
Exercise 2
- Write a map with the days of the week 1 "monday", 2 :"tuesday", etc
- 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] = ???