DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Mastering Advanced Aggregations in Spark SQL
  • Thermometer Continuation in Scala
  • Deploying a Scala Play Application to Heroku: A Step-by-Step Guide
  • Upgrading Spark Pipelines Code: A Comprehensive Guide

Trending

  • Security by Design: Building Full-Stack Applications With DevSecOps
  • IoT and Cybersecurity: Addressing Data Privacy and Security Challenges
  • How GitHub Copilot Helps You Write More Secure Code
  • Prioritizing Cloud Security Risks: A Developer's Guide to Tackling Security Debt
  1. DZone
  2. Coding
  3. Languages
  4. Use of Either in Scala

Use of Either in Scala

In this article, we are going to see the use of Either in Scala. We use options in Scala but why do we want to go for Either? Either is a better approach.

By 
Jyoti Sachdeva user avatar
Jyoti Sachdeva
·
Jul. 06, 20 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
5.2K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, we are going to see the use of Either in scala. We use Options in scala but why do we want to go for Either?

Either is a better approach in the respect that if something fails we can track down the reason, which in Option None case is not possible.

We simply pass None but what is the reason we got None instead of Some. We will see how to tackle this scenario using Either.

Scala
 




xxxxxxxxxx
1


 
1
Either[Left, Right]


None is similar to Left which signifies Failure and Some is similar to Right which signifies Success.

Let's see with help of an example:

Scala
 




x


 
1
 def returnEither(value: String): Either[NumberFormatException, Int] =
2
  {
3
    try {
4
      Right(value.toInt)
5
    } catch {
6
      case ex: NumberFormatException => Left(ex)
7
    }
8
  }
9
returnEither("abc").map(x => println(x))


It will not print anything, Either is right biased and returnEither("abc") gives Left(java.lang.NumberFormatException: For input string: "abc")

Now let's call it on Right value.

Scala
 




xxxxxxxxxx
1


 
1
returnEither("1").map(x => println(x))


It will print 1. Yes, it is right biased as the map works on Either.right. What if i want to call map on left?

Scala
 




xxxxxxxxxx
1


 
1
returnEither("abc").left.map(x => println(x))


It will print java.lang.NumberFormatException: For input string: "abc".

Using Match case with Either

Scala
 




xxxxxxxxxx
1


 
1
 returnEither("1") match
2
  {
3
    case Right(value) => println(s"Right value: $value")
4
    case Left(ex: NumberFormatException) => println(ex)
5
  }


It will print Right value: 1

Extract value from Either

Let's say we want to extract left value from Either.

Scala
 




xxxxxxxxxx
1


 
1
  println(returnEither("abc").left)


will print LeftProjection(Left(java.lang.NumberFormatException: For input string: "abc"))

Scala
 




xxxxxxxxxx
1


 
1
  println(returnEither("1").left)


will print LeftProjection(Right(1))

Scala
 




xxxxxxxxxx
1


 
1
println(returnEither("abc").left.get)


will print java.lang.NumberFormatException: For input string: "abc".

Scala
 




xxxxxxxxxx
1


 
1
println(returnEither("1").left.get)


will print: Exception in thread "main" java.util.NoSuchElementException: Either.left.get on Right

Oops. It had the right value.

We can use getOrElse or fold for default value.

getOrElse

Scala
 




xxxxxxxxxx
1


 
1
println(returnEither("1").left.getOrElse(2)) // will print 2


fold

Scala
 




xxxxxxxxxx
1


 
1
  println(returnEither("1").fold(
2
    i => s"Found an exception: '$i'",
3
    b => s"Found int: '$b'"
4
  ))


will print Found int: '1'

Scala
 




xxxxxxxxxx
1


 
1
  println(returnEither("abc").fold(
2
    i => s"Found an exception: '$i'",
3
    b => s"Found int: '$b'"
4
  ))


will print Found an exception: 'java.lang.NumberFormatException: For input string: "abc"'

Check value is Left or Right

Scala
 




xxxxxxxxxx
1


 
1
  println(returnEither("abc").isLeft) //print true
2
  println(returnEither("1").isRight) // print true


Working with Lists using Either

Scala
 




xxxxxxxxxx
1
14
9


 
1
val list: List[Either[Int, String]] = List(Right("r1"), Left(0), Right("r2"), Left(10), Right("r3"), Left(100), Right("r4"))
2
val newList = list.map(_.map(_.toUpperCase)).map(y => y.left.map(_ * 20))
3
println(newList)


Will give List(Right(R1), Left(0), Right(R2), Left(200), Right(R3), Left(2000), Right(R4)).

Let's understand how. As we know Either is right bias so list.map(x => x.map(_.toUpperCase)), x will only have Right Values which will be converted to uppercase then as we have return type as List[Either[Int, String]] for list.map(_.map(_.toUpperCase)). y will have left and right values. All the left values will be multiplied by 20.

toRight

y.toRight(x) checks if value is empty it return Left(x) else Right(y).

Scala
 




xxxxxxxxxx
1


 
1
val ok: Either[Error, String] = Some("Yeah!").toRight(new Error("Error!"))
2
val error: Either[Error, String] = None.toRight(new Error("Error!"))
3
println(ok) // Right(Yeah!)
4
println(error) // Left(java.lang.Error: Error!)


toLeft

y.toLeft(x) checks if value is empty it return Right(x) else Left(y).

Scala
 




xxxxxxxxxx
1


 
1
val okLeft: Either[Error, String] = Some(new Error("Error!")).toLeft("Yeah!")
2
val errorLeft: Either[Error, String] = None.toLeft("Yeah!")
3
println(okLeft) // Left(java.lang.Error: Error!)
4
println(errorLeft) // Right(Yeah!)


There could be a situation where one function is called then another and then another is a chain and the exceptions are thrown freely. How do we track which function actually caused the exception?

Scala
 




x


 
1
val array: Array[Int] = Array(0,2)
2
def fetchElement(el: Int): Either[Exception, Int] =
3
 if (el < array.length ) Right(array(el))
4
 else Left(new ArrayIndexOutOfBoundsException("from function fetchElement"))
5

          
6
def reciprocal(i: Int): Either[Exception, Double] =
7
 if (i == 0) Left(new IllegalArgumentException("from function reciprocal"))
8
 else Right(1.0 / i)
9

          
10
def stringify(d: Double): String = d.toString
11

          
12
def callFunctions(s: String): Either[Exception, String] = fetchElement(s.toInt).flatMap(reciprocal).map(stringify)
13

          
14
callFunctions("3") match {
15
  case Left(_: ArrayIndexOutOfBoundsException) => println("Exception in fetchElement")
16
  case Left(_: IllegalArgumentException) => println("Exception in reciprocal")
17
  case Left(_) => println("got unknown exception")
18
  case Right(s) => println(s"Got reciprocal: $s")
19
}


will print Exception in fetchElement.

If call callFunctions("0") will print Exception in reciprocal

Thanks for reading!

Scala (programming language)

Published at DZone with permission of Jyoti Sachdeva. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Mastering Advanced Aggregations in Spark SQL
  • Thermometer Continuation in Scala
  • Deploying a Scala Play Application to Heroku: A Step-by-Step Guide
  • Upgrading Spark Pipelines Code: A Comprehensive Guide

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!