Scala Tutorial

Basics

Control Statements

OOP Concepts

Parameterized - Type

Exceptions

Scala Annotation

Methods

String

Scala Packages

Scala Trait

Collections

Scala Options

Miscellaneous Topics

Scala | Either

In Scala, Either is a versatile and commonly-used data type that represents one of two possible values, a value of type A or a value of type B. It is often used to represent the result of a computation that can either succeed with a result or fail with an error. The two possible values that Either can represent are:

  • Left - typically represents the failure or error case.
  • Right - typically represents the success case.

Basic Usage:

Here's how you can create an Either value:

val success: Either[String, Int] = Right(42)
val failure: Either[String, Int] = Left("An error occurred")

In the above example, success is a successful computation that results in an integer, while failure is a computation that results in an error, represented as a string.

Working with Either:

  • Pattern Matching:

You can use pattern matching to destructure and handle Either values:

val result: Either[String, Int] = computeSomething()

result match {
  case Left(error) => println(s"Failed with error: $error")
  case Right(value) => println(s"Success with value: $value")
}

def computeSomething(): Either[String, Int] = {
  // Some computation logic here
  Right(42) // or Left("An error message")
}
  • Map and FlatMap:

Either is right-biased in Scala 2.12 and later, which means that map and flatMap will operate on the Right value:

val result: Either[String, Int] = Right(10)
val squared = result.map(x => x * x)  // Right(100)
  • For Comprehensions:

Thanks to its support for map and flatMap, you can use Either in for comprehensions:

def validateAge(age: Int): Either[String, Int] = 
  if (age >= 0) Right(age) else Left("Negative age")

def validateName(name: String): Either[String, String] =
  if (!name.isEmpty) Right(name) else Left("Empty name")

val result = for {
  age <- validateAge(25)
  name <- validateName("Alice")
} yield s"$name is $age years old."

println(result)  // Right(Alice is 25 years old.)
  • Converting to Options:

You can convert an Either to an Option:

val success: Either[String, Int] = Right(42)
val opt: Option[Int] = success.toOption  // Some(42)

val failure: Either[String, Int] = Left("Error")
val opt2: Option[Int] = failure.toOption  // None

In summary, Either provides a powerful way to handle computations that can succeed or fail. By convention, failures/errors are represented by Left, and successful results by Right, allowing you to write expressive, error-aware code.

  1. Introduction to Either in Scala:

    Either is a data type in Scala used for representing a value that can be either of two types: Left or Right.

    val result: Either[String, Int] = Right(42)
    
  2. Using Either for Error Handling in Scala:

    Either is often used for handling errors by convention, with Left representing an error and Right a successful result.

    def divide(x: Int, y: Int): Either[String, Int] = {
      if (y == 0) Left("Cannot divide by zero")
      else Right(x / y)
    }
    
  3. Either.left and Either.right in Scala:

    Use left and right methods to extract values from Left and Right.

    val result: Either[String, Int] = Left("Error")
    val message = result.left.getOrElse("No error message")
    
  4. Mapping Over Either in Scala:

    Use map to transform the value inside Right without affecting Left.

    val result: Either[String, Int] = Right(42)
    val doubled = result.map(_ * 2)
    
  5. Chaining Either Results in Scala:

    Use flatMap to chain operations on Right values, bypassing Left values.

    val result: Either[String, Int] = Right(21)
    val squaredRoot = result.flatMap(x => if (x >= 0) Right(Math.sqrt(x).toInt) else Left("Negative value"))
    
  6. Combining Either with for-Comprehension in Scala:

    Leverage for comprehension for cleaner syntax when working with multiple Either instances.

    val result: Either[String, Int] = Right(21)
    val result2: Either[String, Int] = Right(3)
    
    val combinedResult = for {
      x <- result
      y <- result2
    } yield x + y
    
  7. Error Recovery with Either in Scala:

    Use fold to recover from errors, providing default values for both Left and Right.

    val result: Either[String, Int] = Left("Error")
    val recovered = result.fold(_ => 0, identity)
    

    Here, identity is used to keep the value unchanged for Right and set a default value for Left.