Tipi di dati algebrici
Modellare il dominio
Tipi di dati algebrici è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Scala for Backend Engineering & Functional Programming, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
Che cos'è un ADT?
Un tipo di dati algebrico (ADT) è un tipo costruito combinando altri tipi. In Scala si modellano gli ADT con un sealed trait e varianti case class e case object.
Gli ADT permettono di descrivere con precisione la struttura dei dati del dominio.
Tipi somma
Un tipo somma indica che un valore è una tra diverse alternative (OR). Un semaforo è Rosso OR Giallo OR Verde.
Lo si esprime con un trait sealed e diverse varianti.
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)
}
}Tipi prodotto
Un tipo prodotto indica che un valore combina diversi campi (AND). Un punto ha una coordinata x AND una coordinata y.
Le case class sono tipi prodotto.
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}")
}
}Combinare tipi somma e prodotto
I veri ADT combinano entrambi: un trait sealed (somma) le cui varianti sono case class (prodotti).
Qui una Shape è un Circle (con raggio) OR un Rectangle (con larghezza e altezza).
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)
}
}Operare su un ADT
Si elabora un ADT eseguendo il pattern matching sulle sue varianti. Ogni ramo gestisce una 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)))
}
}Modellare un dominio
Gli ADT rendono impossibile rappresentare stati non validi. Modelli un metodo di pagamento come un insieme chiuso di opzioni valide.
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 ricorsivi
Un ADT può fare riferimento a se stesso, ed è così che si modellano alberi e liste. Ecco un semplice albero binario.
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)
}
}Fare il fold su un ADT ricorsivo
La ricorsione combinata con il matching permette di elaborare l'intera struttura. Qui sommiamo ogni valore di un albero.
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))
}
}Perché usare gli ADT?
Gli ADT sono potenti perché:
- Descrivono i dati con precisione come somme e prodotti
- Rendono impossibile costruire stati non validi
- Si combinano perfettamente con il pattern matching esaustivo
- Si adattano a strutture ricorsive come alberi e liste
ADT e ereditarietà
La programmazione OOP tradizionale distribuirebbe il comportamento tra le sottoclassi. Gli ADT mantengono chiuse le definizioni dei dati e collocano il comportamento in funzioni che eseguono il pattern matching.
Questa separazione tra dati e comportamento è una caratteristica distintiva della progettazione funzionale.
Mettere insieme i concetti
Un piccolo ADT completo con una funzione che gestisce ogni variante.
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 rapida
Verifichi la Sua comprensione degli ADT.
Riepilogo
Ha imparato a costruire tipi di dati algebrici:
- Tipi somma: trait sealed con più varianti (OR)
- Tipi prodotto: case class con campi (AND)
- Li combini per modellare i domini con precisione
- Gli ADT possono essere ricorsivi (alberi, liste)
- Li elabori con il pattern matching
Domande Frequenti
La lezione «Tipi di dati algebrici» è gratuita?
Sì — il testo completo di «Tipi di dati algebrici» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Scala for Backend Engineering & Functional Programming, passa a CoddyKit PRO. Il corso Scala for Backend Engineering & Functional Programming include 4 lezioni in totale.
Cosa imparerò in «Tipi di dati algebrici»?
Modellare il dominio Eserciti Scala for Backend Engineering & Functional Programming con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Scala for Backend Engineering & Functional Programming?
Non è richiesta alcuna esperienza precedente. Scala for Backend Engineering & Functional Programming su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Tipi di dati algebrici»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Scala for Backend Engineering & Functional Programming?
Sì. Ogni lezione Scala for Backend Engineering & Functional Programming include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Case class
- Trait sealed
- Tipi di dati algebrici
- Corrispondenza esaustiva