typestar

Either for validation in Scala

Either keeps the reason a value was rejected, where a bare Option cannot.

// Either carries a failure on the Left and a success on the Right,
// so the reason for a rejection survives the return trip.
case class Booking(guest: String, nights: Int)

def validate(guest: String, nights: Int): Either[String, Booking] =
  if guest.isEmpty then Left("guest name is required")
  else if nights < 1 then Left(s"$nights nights is not a stay")
  else if nights > 30 then Left("stays over 30 nights need approval")
  else Right(Booking(guest, nights))

// Matching both sides means no failure can be quietly dropped.
def confirm(guest: String, nights: Int): String =
  validate(guest, nights) match
    case Right(booking) => s"booked ${booking.guest} for ${booking.nights}"
    case Left(problem)  => s"rejected: $problem"

// map and getOrElse act on the Right side and leave a Left untouched.
def nightsOrZero(guest: String, nights: Int): Int =
  validate(guest, nights).map(_.nights).getOrElse(0)

How it works

  1. validate returns a Left holding the message, or Right(Booking(guest, nights)) when every rule passes.
  2. The match names both sides, case Right(booking) and case Left(problem), so no failure is dropped.
  3. validate(guest, nights).map(_.nights) acts on the Right side only and leaves a Left alone.

Keywords and builtins used here

The run, in numbers

Lines
19
Characters to type
897
Tokens
162
Three-star pace
70 tpm

At the three-star pace of 70 tokens a minute, this run takes about 139 seconds.

Type this snippet

Step 3 of 3 in Option & Either, step 21 of 27 in Language basics.

← Previous Next →