Julien Truffaut
26th October 2023
In Scala, the Option
type is commonly used to represent situations where data may be absent. However, it lacks the ability to convey why the data is missing. This is where the Either
type comes into play, providing additional context. In this article, we will explore various approaches to convert Option
to Either
and vice versa.
Option
is an enumeration with two possible values: None
and Some
. Pattern matching is a straightforward way to handle these cases. For instance, consider the following code to convert an Option[User]
to an Either[String, User]
:
def getUser(userId: String): Option[User] = ...
getUser("1234") match {
case None => Left("User 1234 is missing")
case Some(user) => Right(user)
}
Pattern matching is simple but can become verbose in nested cases. For example, if we want to find out a user's email address from their user id, the function might fail either because the user doesn't exist or because we don't know their email address.
case class User(id: String, name: String, email: Option[Email])
def getUserEmail(userId: String): Either[String, Email] =
getUser(userId) match {
case None => Left(s"User $userId is missing")
case Some(user) =>
user.email match {
case None => Left(s"User $userId has no email")
case Some(email) => Right(email)
}
}
To streamline the conversion, Scala's Option
provides a method called toRight
that directly transforms a Some
into a Right
and None
into a Left
:
getUser("1234").toRight("User 1234 is missing")
// res: Either[String, User] = Left("User 1234 is missing") OR
// res: Either[String, User] = Right(User(...))
By combining toRight
with a for-comprehension, we can significantly enhance the readability of our code, as shown below:
def getUserEmail(userId: String): Either[String, Email] =
for {
user <- getUser(userId).toRight(s"User $userId is missing")
email <- user.email.toRight(s"User $userId has no email)
} yield email
If you need to convert an Either
back to an Option
, you can easily accomplish this using the toOption
method:
Right(1).toOption
// res: Option[Int] = Some(1)
Left(1).toOption
// res: Option[Nothing] = None
In summary, converting between Option
and Either
in Scala is a common operation when dealing with potential data absence. Pattern matching is the most straightforward approach, but the toRight
method and for-comprehensions provide more concise and readable alternatives. Additionally, Scala's built-in toOption
method makes the reverse conversion from Either
to Option
a breeze. Choose the method that best suits your code and project requirements.