scalabeginner

Sealed Traits and Type Hierarchies

Model domain hierarchies with sealed traits for exhaustive pattern matching and type safety.

scala
// Sealed trait: all subtypes defined in same file
sealed trait PaymentMethod
case class CreditCard(number: String, expiry: String, cvv: String) extends PaymentMethod
case class BankTransfer(iban: String, bic: String) extends PaymentMethod
case class DigitalWallet(provider: String, email: String) extends PaymentMethod
case object Cash extends PaymentMethod

def processPayment(method: PaymentMethod, amount: Double): String =
  method match
    case CreditCard(num, _, _) =>
      val masked = "*" * (num.length - 4) + num.takeRight(4)
      s"Charging $$$amount to card $masked"
    case BankTransfer(iban, _) =>
      s"Transferring $$$amount to $iban"
    case DigitalWallet(provider, email) =>
      s"Sending $$$amount via $provider to $email"
    case Cash =>
      s"Received $$$amount in cash"

// Sealed trait with methods
sealed trait HttpStatus:
  def code: Int
  def isSuccess: Boolean = code >= 200 && code < 300
  def isError: Boolean = code >= 400

case object Ok extends HttpStatus:
  val code = 200
case object NotFound extends HttpStatus:
  val code = 404
case object InternalError extends HttpStatus:
  val code = 500
case class Custom(code: Int, message: String) extends HttpStatus

@main def run(): Unit =
  val payments: List[PaymentMethod] = List(
    CreditCard("4111111111111111", "12/25", "123"),
    BankTransfer("DE89370400440532013000", "COBADEFFXXX"),
    DigitalWallet("PayPal", "alice@test.com"),
    Cash
  )
  payments.foreach(p => println(processPayment(p, 99.99)))

  val statuses: List[HttpStatus] = List(Ok, NotFound, InternalError, Custom(418, "I'm a teapot"))
  statuses.foreach { s =>
    println(s"${s.code}: success=${s.isSuccess}, error=${s.isError}")
  }

Use Cases

  • Payment method modeling
  • HTTP status code handling
  • Exhaustive domain type matching

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.