Chaining Options in Scala
Two dependent lookups and a test, with no null check anywhere.
val owners: Map[String, String] = Map("orders" -> "ada", "billing" -> "grace")
val inboxes: Map[String, String] = Map("ada" -> "Ada@Example.COM")
// flatMap threads one Option-returning step into the next, and map
// transforms the value inside. Two nested null checks become one line.
def inboxFor(team: String): Option[String] =
owners.get(team).flatMap(inboxes.get).map(_.toLowerCase)
// filter keeps the value only when the test passes, else gives None.
def companyInbox(team: String): Option[String] =
inboxFor(team).filter(_.endsWith("@example.com"))
// fold unwraps both cases at once: the default first, then the transform.
def contactLine(team: String): String =
companyInbox(team).fold("no company contact")(mail => s"write to $mail")
How it works
owners.get(team).flatMap(inboxes.get)feeds one lookup straight into the next..map(_.toLowerCase)reaches inside the Option, andfilter(_.endsWith("@example.com"))throws the value away when the test fails.foldunwraps both cases at once, taking the defaultno company contactbefore the transform.
Keywords and builtins used here
MapOptionStringcompanyInboxcontactLinedefinboxForval
The run, in numbers
- Lines
- 15
- Characters to type
- 747
- Tokens
- 128
- Three-star pace
- 65 tpm
At the three-star pace of 65 tokens a minute, this run takes about 118 seconds.
Step 2 of 3 in Option & Either, step 20 of 27 in Language basics.