Comporre IO
Sequenziare gli effetti
Comporre IO è 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.
Concatenare con flatMap
Poiché IO è un monade, si combinano gli effetti con flatMap. Ogni passaggio viene eseguito in ordine e un passaggio successivo può usare il risultato di uno precedente.
import cats.effect.IO
val program: IO[Unit] =
IO("Alice").flatMap(name => IO.println(s"Hello, $name"))for-comprehension
Una for-comprehension viene desugared in flatMap/map e ha l'aspetto di uno script imperativo, pur rimanendo pura.
import cats.effect.IO
val prog: IO[Unit] = for {
_ <- IO.println("What is your name?")
name <- IO("Bob")
_ <- IO.println(s"Hi $name")
} yield ()L'ordine viene preservato
Gli effetti in una for-comprehension vengono eseguiti dall'alto verso il basso quando il programma viene eseguito. La struttura del codice rispecchia l'ordine di esecuzione.
Combinare effetti indipendenti
Quando due effetti non dipendono l'uno dall'altro, usi mapN o (a, b).tupled per combinarli. Per impostazione predefinita vengono comunque eseguiti in sequenza, ma in questo modo se ne esprime l'indipendenza.
import cats.effect.IO
import cats.syntax.apply._
val combined: IO[Int] = (IO(2), IO(3)).mapN(_ + _)Eseguire effetti in parallelo
Usi parMapN (da cats.syntax.parallel) per eseguire contemporaneamente effetti indipendenti su fiber separate e combinarne i risultati.
import cats.effect.IO
import cats.syntax.parallel._
val par: IO[Int] = (IO(2), IO(3)).parMapN(_ + _)Ignorare i risultati
Usi *> per eseguire un effetto e mantenere il secondo risultato, oppure <* per mantenere il primo. void ignora completamente il risultato e produce IO[Unit].
import cats.effect.IO
val r1: IO[Int] = IO.println("log") *> IO(42)
val r2: IO[Unit] = IO(99).voidRipetere gli effetti
replicateA(n) esegue un effetto n volte e raccoglie i risultati in una lista. foreverM lo ripete indefinitamente.
import cats.effect.IO
val three: IO[List[Unit]] = IO.println("tick").replicateA(3)Attraversare una List
Trasformi una List[A] in un effetto su una List[B] con traverse. Ogni elemento produce un IO e i risultati vengono raccolti.
import cats.effect.IO
import cats.syntax.traverse._
val names = List("a", "b", "c")
val prog: IO[List[Unit]] = names.traverse(n => IO.println(n))parTraverse
parTraverse è la versione parallela di traverse: l'effetto di ogni elemento viene eseguito sulla propria fiber, una soluzione ideale per operazioni di I/O concorrenti, come recuperare molti URL.
import cats.effect.IO
import cats.syntax.parallel._
val ids = List(1, 2, 3)
val prog: IO[List[Int]] = ids.parTraverse(id => IO(id * 10))Un programma composto
Questo programma legge un valore, lo raddoppia e stampa il risultato, il tutto composto da piccoli passaggi IO in un'unica descrizione.
import cats.effect.{IO, IOApp}
object Doubler extends IOApp.Simple {
def run: IO[Unit] = for {
n <- IO(21)
d = n * 2
_ <- IO.println(s"Doubled: $d")
} yield ()
}Concatenazione in Scala normale
Per confronto, ecco l'output sequenziale della console in Scala normale: eager e impuro, a differenza della versione IO rimandata precedente.
object Main {
def main(args: Array[String]): Unit = {
val n = 21
val d = n * 2
println(s"Doubled: $d")
}
}Verifica rapida
Quale metodo esegue contemporaneamente due effetti indipendenti e ne combina i risultati?
Riepilogo
Ha composto programmi IO con:
flatMapeforper la concatenazionemapN/parMapNper gli effetti indipendenti*>,<*,voidper combinare o ignorare i risultatitraverse/parTraverseper le collezioni
Prossimo argomento: gestire gli errori all'interno di IO.
Domande Frequenti
La lezione «Comporre IO» è gratuita?
Sì — il testo completo di «Comporre IO» è 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 «Comporre IO»?
Sequenziare gli effetti 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 «Comporre IO»?
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.