0Pricing
Scala for Backend Engineering & Functional Programming · Lezione

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).void

Ripetere 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:

  • flatMap e for per la concatenazione
  • mapN / parMapN per gli effetti indipendenti
  • *>, <*, void per combinare o ignorare i risultati
  • traverse / parTraverse per 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.

Tutte le lezioni di questo corso

  1. Type class di Cats
  2. La monade IO
  3. Comporre IO
  4. Gestire gli errori in IO
← Torna a Scala for Backend Engineering & Functional Programming