Komponowanie IO
Sekwencjonowanie efektów
Komponowanie IO to bezpłatna lekcja Scala for Backend Engineering & Functional Programming na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Scala for Backend Engineering & Functional Programming, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Porządkowanie za pomocą flatMap
Ponieważ IO jest monadą, efekty komponuje się za pomocą flatMap. Każdy krok jest wykonywany po kolei, a późniejszy krok może korzystać z wyniku wcześniejszego.
import cats.effect.IO
val program: IO[Unit] =
IO("Alice").flatMap(name => IO.println(s"Hello, $name"))for-comprehension
Wyrażenie for jest rozwijane do flatMap/map i przypomina skrypt imperatywny, zachowując przy tym czystość.
import cats.effect.IO
val prog: IO[Unit] = for {
_ <- IO.println("What is your name?")
name <- IO("Bob")
_ <- IO.println(s"Hi $name")
} yield ()Kolejność jest zachowana
Efekty w wyrażeniu for są wykonywane od góry do dołu podczas uruchamiania programu. Struktura kodu odzwierciedla kolejność wykonania.
Łączenie niezależnych efektów
Gdy dwa efekty nie zależą od siebie, użyj mapN lub (a, b).tupled, aby je połączyć. Domyślnie nadal są wykonywane sekwencyjnie, ale kod wyraża ich niezależność.
import cats.effect.IO
import cats.syntax.apply._
val combined: IO[Int] = (IO(2), IO(3)).mapN(_ + _)Równoległe uruchamianie efektów
Użyj parMapN (z cats.syntax.parallel), aby równolegle wykonywać niezależne efekty na osobnych włóknach i łączyć ich wyniki.
import cats.effect.IO
import cats.syntax.parallel._
val par: IO[Int] = (IO(2), IO(3)).parMapN(_ + _)Odrzucanie wyników
Użyj *>, aby wykonać efekt i zachować drugi wynik, albo <*, aby zachować pierwszy. void całkowicie odrzuca wynik, zwracając IO[Unit].
import cats.effect.IO
val r1: IO[Int] = IO.println("log") *> IO(42)
val r2: IO[Unit] = IO(99).voidPowtarzanie efektów
replicateA(n) wykonuje efekt n razy i zbiera wyniki do listy. foreverM powtarza go bez końca.
import cats.effect.IO
val three: IO[List[Unit]] = IO.println("tick").replicateA(3)Przechodzenie po liście
Za pomocą traverse zamień List[A] w efekt działający na List[B]. Każdy element tworzy IO, a wyniki są zbierane.
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 to równoległa wersja traverse — efekt każdego elementu jest wykonywany na osobnym włóknie, co doskonale sprawdza się przy współbieżnych operacjach I/O, takich jak pobieranie wielu adresów 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))Skomponowany program
Ten program odczytuje wartość, podwaja ją i wypisuje wynik — wszystko jest skomponowane z małych kroków IO w jednym opisie.
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 ()
}Sekwencjonowanie w zwykłej Scali
Dla porównania przedstawiono tu sekwencyjny wynik w konsoli w zwykłej Scali — zachłanny i nieczysty, w przeciwieństwie do przedstawionej wyżej odroczonej wersji z IO.
object Main {
def main(args: Array[String]): Unit = {
val n = 21
val d = n * 2
println(s"Doubled: $d")
}
}Szybkie sprawdzenie
Która metoda wykonuje współbieżnie dwa niezależne efekty i łączy ich wyniki?
Podsumowanie
Skomponowałeś programy IO za pomocą:
flatMapifordo sekwencjonowaniamapN/parMapNdo obsługi niezależnych efektów*>,<*,voiddo łączenia i odrzucania wynikówtraverse/parTraversedo pracy z kolekcjami
Następnie: obsługa błędów wewnątrz IO.
Często zadawane pytania
Czy lekcja „Komponowanie IO” jest bezpłatna?
Tak — pełny tekst „Komponowanie IO” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Scala for Backend Engineering & Functional Programming, przejdź na CoddyKit PRO. Kurs Scala for Backend Engineering & Functional Programming zawiera 4 lekcji w sumie.
Co nauczysz się w „Komponowanie IO”?
Sekwencjonowanie efektów Ćwiczysz Scala for Backend Engineering & Functional Programming z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Scala for Backend Engineering & Functional Programming?
Nie wymagamy żadnego doświadczenia. Scala for Backend Engineering & Functional Programming w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Komponowanie IO”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Scala for Backend Engineering & Functional Programming?
Tak. Każda lekcja Scala for Backend Engineering & Functional Programming zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Type classy Cats
- Monada IO
- Komponowanie IO
- Obsługa błędów w IO