scalabeginner

Tuples and Product Types

Work with Scala 3 tuples: named tuples, tuple operations, conversions, and generic programming.

scala
// Basic tuples
val pair: (Int, String) = (1, "hello")
val triple: (Int, String, Boolean) = (1, "hello", true)

// Access elements
val first = pair._1     // 1
val second = pair._2    // "hello"

// Destructuring
val (x, y) = pair
val (a, b, c) = triple

// Tuple operations (Scala 3)
val t1 = (1, "a", true)
val t2 = (2.0, 'x')

// Concatenation
val combined: (Int, String, Boolean, Double, Char) = t1 ++ t2

// Map
val mapped = (1, 2, 3).map[[X] =>> Int]([T] => (t: T) => t match
  case i: Int => i * 2
)

// Converting between tuples and case classes
case class Point(x: Double, y: Double, z: Double)

val pointTuple = (1.0, 2.0, 3.0)
val point = Point.apply.tupled(pointTuple)  // Tuple to case class

// Tuple from case class (via productIterator)
val backToTuple = Tuple.fromProduct(point)

@main def run(): Unit =
  println(s"Pair: $pair")
  println(s"First: $first, Second: $second")
  println(s"Destructured: x=$x, y=$y")
  println(s"Combined: $combined")

  // Swap pair
  val swapped = pair.swap
  println(s"Swapped: $swapped")

  // Tuple in collections
  val inventory = List(
    ("Apple", 2.5, 100),
    ("Banana", 1.0, 200),
    ("Cherry", 4.0, 50)
  )

  // Sort by price
  val byPrice = inventory.sortBy(_._2)
  println(s"By price: $byPrice")

  // Unzip
  val (names, prices, quantities) = inventory.unzip3
  println(s"Names: $names")
  println(s"Prices: $prices")

  // Zip
  val zipped = names.zip(prices)
  println(s"Zipped: $zipped")

  // Pattern matching with tuples
  val point2d = (3, 4)
  point2d match
    case (0, 0) => println("Origin")
    case (x, 0) => println(s"On x-axis at $x")
    case (0, y) => println(s"On y-axis at $y")
    case (x, y) => println(s"Point at ($x, $y)")

  // Tuple as function arguments
  def distance(p: (Double, Double)): Double =
    val (px, py) = p
    Math.sqrt(px * px + py * py)

  println(f"Distance: ${distance((3.0, 4.0))}%.2f")

  // Product iterator
  val values = point.productIterator.toList
  println(s"Point values: $values")
  println(s"Point fields: ${point.productElementNames.toList}")

Use Cases

  • Returning multiple values from functions
  • Temporary data grouping
  • Destructuring and pattern matching

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.