Summary: This post is a discussion of the “Option
/Some
/None
Pattern” in Scala, specifically how to use the Either
/Left
/Right
data types instead of Option when you need to know the reason some code failed. As you may know, the None data type does not return failure/exception information, but if you use the Either
/Left
/Right
types, you can access that failure information through the Left
type.
The post is sponsored by my book, the 2nd Edition of the Scala Cookbook.
A type like Option, but gives you more information
A Scala idiom (best practice) is to use the Option
/Some
/None
pattern instead of using exceptions along with try/catch/finally (especially using Option
/Some
/None
instead of using null values). While using Option
is generally a much better approach, one weakness of this approach is that the Option
/Some
/None
approach doesn’t tell you why something failed, that is, why you got a None
instead of a Some
.
When you want to see that information about why something failed, you have two choices that are built into Scala:
- The Scala
Try
/Success
/Failure
classes - The
Either
/Left
/Right
classes
This tutorial demonstrates Either, with its companions Left and Right.
Scala’s Either, Left, and Right
Either
works just like Option
, with a difference being that with Either
you can return a String
that describes the problem that occurred. Actually, what you do is wrap the String
inside of Left
.
Actually ... what you really do is return anything you want inside of Left
, though returning information about the problem is generally the intention, so as a practical matter you typically return a String
or Throwable
. Before I move on, this is a key point:
Because you can return anything you want,
Either
is more flexible thanTry
.
Here’s a quick comparison of the Option
and Either
approaches:
Either
is just likeOption
Right
is just likeSome
, so you use it to return the “success” caseLeft
is just likeNone
, except you can include content with it to describe the “failure” case
A Scala Either/Left/Right example
Here’s a look at how Either
works in a simple example:
object EitherLeftRightExample extends App { /** * A method to demonstrate how to declare that a method returns an Either, * and code that returns a Left or Right. 'Left' is a String that represents * the potential error, and 'Right' is an Int that contains the value you * want when everything goes well. * https://alvinalexander.com */ def divideXByY(x: Int, y: Int): Either[String, Int] = { if (y == 0) Left("Dude, can't divide by 0") else Right(x / y) } // a few different ways to use Either, Left, and Right println(divideXByY(1, 0)) println(divideXByY(1, 1)) divideXByY(1, 0) match { case Left(s) => println(s"Error: $s") case Right(i) => println(s"Answer: $i") } }
Discussion
In that example, the method divideXByY
returns an Either
, specifically this Either
:
Either[String, Int]
In this example, the thing on the left is a String
, and the thing on the right is an Int
. As I note in the comments, the Left
value will contain the error information if something goes wrong, and the Right
value will contain the Int
value you want if everything goes well.
I don’t know the historical background of Left
and Right
yet, so the way I remember them is to think of Right
as meaning “right,” as in “correct.” The only place left and right have a whole lot of meaning to me is in the declaration of Either[left-type, right-type]
, where Left
is on the left, and Right
is on the right.
If you’re familiar with the Option/Some/None pattern, you can see that using Either
is only a slight difference from using that pattern. Again, the intent of using Either
is to pass a message back about what went wrong, so you can return the error message from an exception, or anything else you want to return with the Left
instance.
In case nothing I’ve written makes any sense, here’s a description of Either
from its Scaladoc:
Represents a value of one of two possible types (a disjoint union.) Instances of Either are either an instance of Left or Right.
A common use of
Either
is as an alternative toOption
for dealing with possible missing values. In this usage,scala.None
is replaced with aLeft
which can contain useful information.Right
takes the place ofSome
. Convention dictates thatLeft
is used for failure andRight
is used for success.
The Scala Either, Left, and Right classes
I’ll be glad to write more about this if anyone is interested, but for now, here are links to the Scala Either
, Left
, and Right
classes:
While I’m in the neighborhood, here are links to the Option
and Some
classes, and the None
object:
The Scala Try/Success/Failure classes are similar to Either
, but as I’ve learned over time, because you have more control over the error type, Either
is more flexible than Try
, so I’ve begun to use Either
more myself.
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |
In summary, I hope this discussion of Scala’s Either
, Left
, and Right
classes has been helpful.