Tipos de dados algébricos
Modele seu domínio.
Tipos de dados algébricos é uma aula grátis de Scala for Backend Engineering & Functional Programming no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Scala for Backend Engineering & Functional Programming, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.
O que é um ADT?
Um tipo de dados algébrico (ADT) é um tipo criado pela combinação de outros tipos. Em Scala, você modela ADTs com um sealed trait e variantes de case class e case object.
Os ADTs permitem descrever com precisão a forma dos dados do seu domínio.
Tipos soma
Um tipo soma significa que um valor é uma de várias alternativas (um OR). Um semáforo é Vermelho OR Amarelo OR Verde.
Você expressa isso com um trait selado e várias 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 produto
Um tipo produto significa que um valor combina vários campos (um AND). Um ponto tem um x AND um y.
As classes de caso são tipos produto.
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}")
}
}Combinando tipos soma e produto
Os ADTs reais combinam ambos: um trait selado (soma) cujas variantes são classes de caso (produtos).
Aqui, uma Shape é um Circle (com raio) OR um Rectangle (com largura e 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)
}
}Operando em um ADT
Você processa um ADT usando correspondência de padrões em suas variantes. Cada ramo trata de uma forma.
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)))
}
}Modelando um domínio
Os ADTs tornam os estados inválidos impossíveis de representar. Modele um método de pagamento como um conjunto fechado de opções 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)
}
}ADTs recursivos
Um ADT pode referir-se a si próprio, permitindo modelar árvores e listas. Aqui está uma árvore binária simples.
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)
}
}Percorrendo um ADT recursivo
A recursão combinada à correspondência permite processar toda a estrutura. Aqui, somamos cada valor de uma árvore.
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 que usar ADTs?
Os ADTs são poderosos porque:
- Descrevem os dados com precisão como somas e produtos
- Tornam impossível construir estados ilegais
- Combinam perfeitamente com a correspondência exaustiva de padrões
- Podem ser ampliados para estruturas recursivas, como árvores e listas
ADTs versus herança
A POO tradicional espalharia o comportamento pelas subclasses. Os ADTs mantêm as definições de dados fechadas e colocam o comportamento em funções que usam correspondência de padrões.
Essa separação entre dados e comportamento é uma característica marcante do design funcional.
Reunindo tudo
Um pequeno ADT completo com uma função que trata de todas as 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)))
}
}Verificação rápida
Teste sua compreensão sobre ADTs.
Recapitulação
Você aprendeu a criar tipos de dados algébricos:
- Tipos soma: trait selado com várias variantes (OR)
- Tipos produto: classes de caso com campos (AND)
- Combine-os para modelar domínios com precisão
- Os ADTs podem ser recursivos (árvores e listas)
- Processe-os com correspondência de padrões
Perguntas Frequentes
A aula “Tipos de dados algébricos” é grátis?
Sim — o texto completo de “Tipos de dados algébricos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Scala for Backend Engineering & Functional Programming, atualize para CoddyKit PRO. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.
O que vou aprender em “Tipos de dados algébricos”?
Modele seu domínio. Você pratica Scala for Backend Engineering & Functional Programming com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Scala for Backend Engineering & Functional Programming?
Nenhuma experiência prévia é necessária. Scala for Backend Engineering & Functional Programming no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Tipos de dados algébricos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Scala for Backend Engineering & Functional Programming?
Sim. Cada aula de Scala for Backend Engineering & Functional Programming inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Classes case
- Traits seladas
- Tipos de dados algébricos
- Correspondência exaustiva