Las tuplas son una colección que permite agrupar elementos del mismo tipo, sin embargo a diferencia de la listas no son recursivas, es una abstracción de los arreglos, porque estas permiten abstraer diferentes patrones.
scala> scala.Tuple2(1,2)
val res3: (Int, Int) = (1,2)
scala> (1,2)
val res4: (Int, Int) = (1,2)
Las tuplas nos permiten hacer reconocimiento de patrones en diferentes ambitos, entre ellos la ligadura de variables
scala> val (x,y) = (1,2)
val x: Int = 1
val y: Int = 2
Tuplas en reconocimiento de patrones¶
En ciertas ocasiones necesitamos que reconocer dos o mas patrones al mismo tipo.
Suma de vectores¶
Dados
Para sumarlos
object SumarL{
// Función que suma dos listas elemento por elemento usando pattern matching anidado
def sumarv1(u:List[Int], v:List[Int]):List[Int] = {
u match {
case Nil => { // Caso cuando la primera lista está vacía
v match {
case Nil => Nil // Ambas listas vacías - retorna lista vacía
case _ => throw new Exception("Las listas no tienen el mismo tamanio") // Listas de diferente tamaño
}
}
case h :: t => { // Caso cuando la primera lista tiene elementos
v match {
case Nil => throw new Exception("Las listas no tienen el mismo tamanio") // Listas de diferente tamaño
case x :: xs => h + x :: sumarv1(t, xs) // Suma elementos cabeza y procesa recursivamente las colas
}
}
}
}
// Función que suma dos listas usando pattern matching con tuplas (más conciso)
def sumarv2(u:List[Int], v:List[Int]):List[Int] = {
(u,v) match { // Pattern matching sobre la tupla (u,v)
case (Nil, Nil) => Nil // Ambas listas vacías
case (Nil, _) => throw new Exception("Las listas no tienen el mismo tamanio") // Primera lista vacía, segunda no
case (_, Nil) => throw new Exception("Las listas no tienen el mismo tamanio") // Segunda lista vacía, primera no
case (x::xs,y::ys) => x + y:: sumarv1(xs, ys) // Ambas tienen elementos - suma y procesa recursivamente
}
}
// Función principal para probar las implementaciones
def main(args:Array[String]):Unit = {
val u = List(1,2,3,4,5,6) // Primera lista de prueba
val v = List(2,4,6,8,10,12) // Segunda lista de prueba
println(sumarv1(u,v)) // Prueba de sumarv1
println(sumarv2(u,v)) // Prueba de sumarv2
}
}
Comentario del código¶
Este código Scala implementa dos versiones de una función que suma dos listas de enteros elemento por elemento:
sumarv1¶
- Enfoque: Anidamiento de patrones
- Funcionamiento:
- Primero hace pattern matching sobre
u - Si
ues vacía, verifica sivtambién lo es - Si
utiene elementos, verifica quevtambién los tenga - Suma recursivamente los elementos cabeza y procesa las colas
sumarv2¶
- Enfoque: Pattern matching con tuplas
- Funcionamiento:
- Hace pattern matching directamente sobre la tupla
(u, v) - Analiza simultáneamente el estado de ambas listas
- Casos más claros y concisos
Ventajas de usar tuplas en pattern matching¶
1. Sintaxis más limpia y concisa¶
// Con tuplas (sumarv2)
case (x::xs, y::ys) => x + y :: sumarv1(xs, ys)
// Sin tuplas (sumarv1)
case h :: t => {
v match {
case x :: xs => h + x :: sumarv1(t, xs)
2. Análisis simultáneo¶
Las tuplas permiten analizar múltiples valores al mismo tiempo, lo que es especialmente útil cuando los casos están relacionados (como verificar que ambas listas tengan la misma estructura).
3. Mejor manejo de casos relacionados¶
Los casos como (Nil, Nil), (Nil, _), (_, Nil) expresan claramente la relación entre los estados de ambas listas.
4. Reducción de código repetitivo¶
Elimina la necesidad de verificar manualmente la correspondencia entre los diferentes casos de las listas.
5. Mantenibilidad¶
Es más fácil añadir nuevos casos o modificar la lógica cuando todos los patrones relacionados están en un solo bloque de matching.
Salida esperada: List(3, 6, 9, 12, 15, 18) para ambas funciones, ya que suman (1+2, 2+4, 3+6, 4+8, 5+10, 6+12).