0Pricing
Scala for Backend Engineering & Functional Programming · Lección

Tipos de datos algebraicos

Modele su dominio

Tipos de datos algebraicos es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.

¿Qué es un ADT?

Un tipo de datos algebraico (ADT) es un tipo creado al combinar otros tipos. En Scala, los ADT se modelan con un sealed trait y variantes case class y case object.

Los ADT permiten describir con precisión la estructura de los datos del dominio.

Tipos suma

Un tipo suma significa que un valor es una de varias alternativas (un OR). Un semáforo es Rojo O Amarillo O Verde.

Esto se expresa mediante un sealed trait y varias variantes.

sealed trait Light
case object Red extends Light
case object Yellow extends Light
case object Green extends Light
object Main {
  def main(args: Array[String]): Unit = {
    val l: Light = Yellow
    println(l)
  }
}

Tipos producto

Un tipo producto significa que un valor combina varios campos (un AND). Un punto tiene una coordenada x Y una coordenada y.

Las clases case son tipos producto.

case class Point(x: Int, y: Int)
object Main {
  def main(args: Array[String]): Unit = {
    val p = Point(3, 4)
    println(s"${p.x} and ${p.y}")
  }
}

Combinar tipos suma y producto

Los ADT reales combinan ambos conceptos: un sealed trait (suma) cuyas variantes son clases case (productos).

Aquí, Shape es un Circle (con radio) O un Rectangle (con anchura y altura).

sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(w: Double, h: Double) extends Shape
object Main {
  def main(args: Array[String]): Unit = {
    val s: Shape = Rectangle(3, 4)
    println(s)
  }
}

Operar sobre un ADT

Los ADT se procesan mediante pattern matching sobre sus variantes. Cada rama gestiona una figura.

sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(w: Double, h: Double) extends Shape
object Main {
  def area(s: Shape): Double = s match {
    case Circle(r)       => 3.14159 * r * r
    case Rectangle(w, h) => w * h
  }
  def main(args: Array[String]): Unit = {
    println(area(Circle(2)))
    println(area(Rectangle(3, 4)))
  }
}

Modelar un dominio

Los ADT hacen que los estados no válidos no se puedan representar. Modele un método de pago como un conjunto cerrado de opciones válidas.

sealed trait PaymentMethod
case class CreditCard(number: String) extends PaymentMethod
case class BankTransfer(iban: String) extends PaymentMethod
case object Cash extends PaymentMethod
object Main {
  def main(args: Array[String]): Unit = {
    val m: PaymentMethod = Cash
    println(m)
  }
}

ADT recursivos

Un ADT puede referirse a sí mismo, lo que permite modelar árboles y listas. Este es un árbol binario sencillo.

sealed trait Tree
case object Leaf extends Tree
case class Node(value: Int, left: Tree, right: Tree) extends Tree
object Main {
  def main(args: Array[String]): Unit = {
    val t: Tree = Node(1, Leaf, Node(2, Leaf, Leaf))
    println(t)
  }
}

Plegar un ADT recursivo

La recursividad junto con el pattern matching permite procesar toda la estructura. Aquí sumamos todos los valores de un árbol.

sealed trait Tree
case object Leaf extends Tree
case class Node(value: Int, left: Tree, right: Tree) extends Tree
object Main {
  def sum(t: Tree): Int = t match {
    case Leaf            => 0
    case Node(v, l, r)   => v + sum(l) + sum(r)
  }
  def main(args: Array[String]): Unit = {
    val t = Node(1, Node(2, Leaf, Leaf), Node(3, Leaf, Leaf))
    println(sum(t))
  }
}

¿Por qué usar ADT?

Los ADT son potentes porque:

  • Describen los datos con precisión mediante sumas y productos
  • Hacen imposible construir estados ilegales
  • Combinan perfectamente con el pattern matching exhaustivo
  • Se adaptan a estructuras recursivas como árboles y listas

ADT frente a herencia

La POO tradicional dispersaría el comportamiento entre las subclases. Los ADT mantienen cerradas las definiciones de datos y colocan el comportamiento en funciones que usan pattern matching.

Esta separación entre datos y comportamiento es característica del diseño funcional.

Unirlo todo

Un ADT pequeño completo con una función que gestiona todas las variantes.

sealed trait Json
case class JNum(n: Double) extends Json
case class JStr(s: String) extends Json
case object JNull extends Json
object Main {
  def render(j: Json): String = j match {
    case JNum(n) => n.toString
    case JStr(s) => "\"" + s + "\""
    case JNull   => "null"
  }
  def main(args: Array[String]): Unit = {
    List(JNum(3.0), JStr("hi"), JNull).foreach(j => println(render(j)))
  }
}

Comprobación rápida

Compruebe su comprensión de los ADT.

Resumen

Ha aprendido a construir tipos de datos algebraicos:

  • Tipos suma: sealed trait con varias variantes (OR)
  • Tipos producto: clases case con campos (AND)
  • Combínelos para modelar dominios con precisión
  • Los ADT pueden ser recursivos (árboles y listas)
  • Procéselos mediante pattern matching

Preguntas frecuentes

¿La lección «Tipos de datos algebraicos» es gratis?

Sí — el texto completo de «Tipos de datos algebraicos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.

¿Qué aprenderé en «Tipos de datos algebraicos»?

Modele su dominio Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?

No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Tipos de datos algebraicos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?

Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Clases case
  2. Traits sellados
  3. Tipos de datos algebraicos
  4. Coincidencia exhaustiva
← Volver a Scala for Backend Engineering & Functional Programming