Diving deeper into Scala’s Option, Try & Either

case class Contact(id: Int, name: String, phone: Option[String],
email: Option[String], friendIds: List[Int])
def dbLookup(id: Int): Try[Contact]
def sendEmail(email: String): Boolean
def inviteFriends: List[Int] = {

var successes: List[Int] = List.empty

for (id <- friendIds) {
val record = dbLookup(id)
if (record.isSuccess) {
val maybeEmail = record.get.email
if (maybeEmail.isDefined) {
val send = sendEmail(maybeEmail.get)
if (send) successes = id :: successes
}
}
}

successes
}
def inviteFriends: List[Int] = {
val successes = friendIds.map { id =>
dbLookup(id) match {
case Failure(exception) => None
case Success(friend) => {
friend.email match {
case Some(email) => if (sendEmail(email)) Some(id) else None
case None => None
}
}
}
}
successes.filter(_.isDefined).map(_.get)
}

Map to the Rescue

def inviteFriends: List[Int] = {

val successes = friendIds.map { id =>
dbLookup(id).map { contact =>
contact.email.map { address =>
sendEmail(address)
}
}
}

??? // successes is now of type List[Try[Option[Boolean]]]
}
def inviteFriends: List[Int] = {

val successes = friendIds.map { id =>
dbLookup(id).map { contact =>
contact.email.map { address =>
if (sendEmail(address)) Some(id) else None
}
}
}

??? // successes is now of type List[Try[Option[Option[Int]]]]
}
def inviteFriends: List[Int] = {

val successes = friendIds.map { id =>
dbLookup(id).map { contact =>
contact.email.map { address =>
if (sendEmail(address)) Some(id) else None
}
}
}

success.filter(s => s.isSuccess && s.get.isDefined &&
s.get.get.isDefined)
.map(_.get.get.get)
}

Boxes within Boxes (“It’s turtles all the way down!”)

Each of these hold a value of type T in the happy path.

Almost Done!

def inviteFriends: List[Int] = {

val successes = friendIds
.flatMap(id => dbLookup(id).toOption
.flatMap(contact => contact.email)
.filter(sendEmail).map(_ => id))

successes
}

--

--

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