Scala for Beginners: How to really use Option (and Try and Either)

Stick figure saying “I think I get the gist of this. It can’t be too hard to use…”
case class Person(name: String, 
age: Option[Int],
email: Option[String])
def sendEmail(address: String): Boolean
// returns true is successful
def invite(guest: Person): Boolean = {
if (
println("Guest's email is " + guest.getOrElse("unknown"))


First lesson: pattern matching

def invite(guest: Contact): Boolean = match {
case Some(e) => sendEmail(e) // returns true if successful
case None => false
scala> def invite(guest: Option[String]): Boolean = guest match {
| case Some(e) => println(e)
| }
warning: match may not be exhaustive.
It would fail on the following input: None

Second lesson: map

scala> List("one","two","three").map(s => s.size)
val res1: List[Int] = List(3, 3, 5)
scala> def stringSize(o: Option[String]) = => s.size)
def stringSize(o: Option[String]): Option[Int]
scala> stringSize(Some("Hello"))
val res2: Option[Int] = Some(5)
scala> stringSize(None)
val res3: Option[Int] = None
scala> List("one","two","three").map(_.size)
val res1: List[Int] = List(3, 3, 5)
scala> def stringSize(s: Option[String]) =

Let’s look at the sibling typeclass Try

scala> def convert(n: String): Try[Int] = Try(n.toInt)
def convert(n: String): scala.util.Try[Int]
scala> convert("3")
val res6: scala.util.Try[Int] = Success(3)
scala> convert("foo")
val res7: scala.util.Try[Int] = Failure(java.lang.NumberFormatException: For input string: "foo")
scala> convert("5").toOption
val res10: Option[Int] = Some(5)
scala> convert("bar").toOption
val res11: Option[Int] = None
val email: Try[String] = getEmail("bob")
val success: Boolean = if (email.isSuccess) {
} else {
val email: Try[String] = getEmail("bob")
val success = email match {
case Success(addr) => sendEmail(addr) // returns true if success
case Failure(e) => false
val email: Try[String] = getEmail("bob")
val success = => sendEmail(addr)).toOption
val success =
  1. Some(true) if the sendEmail function returned true indicating successful delivery.
  2. Some(false) if sendEmail ran into some problem
  3. None if the earlier getEmail function failed.

While we’re at it, let’s look at Either

def getEmail(custID: String): Either[Int,String]
val email: Left[String] = getEmail("bob")
val status: Either[String, String] = email match {
case Failure(e) => Left("Couldn't get email address")
case Success(e) => {
if (sendEmail(e))
Left("Couldn't deliver invite")



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Murray Todd Williams

Murray Todd Williams


Life-long learner, foodie and wine enthusiast, living in Austin, Texas.