DSL Raise w Arrow: składanie typowanych błędów
Użyj kontekstu Raise w Arrow oraz raise(), aby przejrzyście składać przepływy z wieloma błędami.
DSL Raise w Arrow: składanie typowanych błędów to bezpłatna lekcja Kotlin Academy na CoddyKit. To lekcja 2 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 Kotlin Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Ograniczenia łączenia Either
Łączenie Either za pomocą flatMap prowadzi do głęboko zagnieżdżonych lambd, gdy występuje wiele sekwencyjnych operacji. Raise DSL biblioteki Arrow (wprowadzony w Arrow 1.2) oferuje czytelniejszą składnię w stylu korutyn, korzystającą z odbiorników kontekstu lub funkcji rozszerzających Kotlina.
Czym jest Raise<E>?
Raise to kontekst, który może zgłosić błąd typu E i przerwać dalsze wykonywanie. Funkcja, która może zakończyć się niepowodzeniem, wywołuje raise(error), aby przerwać działanie i propagować błąd — podobnie jak przy rzucaniu wyjątku, ale bez wyjątków.
Konstruktor either { }
Konstruktor either { } tworzy obiekt Either na podstawie bloku, w którym dostępny jest kontekst Raise. Wewnątrz bloku należy wywołać raise(error) w przypadku niepowodzenia albo po prostu zwrócić wartość w przypadku powodzenia:
import arrow.core.raise.either
import arrow.core.raise.Raise
fun validateAge(age: Int): Either<String, Int> = either {
if (age < 0) raise("Age cannot be negative")
if (age > 150) raise("Age too large")
age
}bind() — rozpakowywanie Either wewnątrz either{}
Wewnątrz bloku either { } należy wywołać .bind() na dowolnej wartości Either, aby ją rozpakować. Jeśli jest to Left, bind() automatycznie zgłasza błąd i przerywa działanie bloku:
fun createUser(name: String, age: Int): Either<String, User> = either {
val validName = validateName(name).bind() // raises if Left
val validAge = validateAge(age).bind() // raises if Left
User(validName, validAge) // only reached if both succeed
}ensure() — sprawdzanie warunku w miejscu użycia
ensure(condition) { error } to skrót dla if (!condition) raise(error). Pozwala zachować zwięzłość logiki walidacji:
fun validateEmail(email: String): Either<String, String> = either {
ensure(email.contains("@")) { "Email must contain @" }
ensure(email.length <= 255) { "Email too long" }
email
}ensureNotNull() — sprawdzanie wartości null za pomocą Raise
ensureNotNull(value) { error } rozpakowuje wartość nullable albo zgłasza błąd, jeśli jest ona równa null:
fun findUser(id: Long, repo: UserRepo): Either<UserError, User> = either {
ensureNotNull(repo.findById(id)) { UserError.NotFound(id) }
}Raise z odbiornikami kontekstu (Arrow 1.2+)
Można bezpośrednio deklarować funkcje wymagające kontekstu Raise, bez opakowywania ich w either { }:
context(Raise<String>)
fun requirePositive(n: Int): Int {
ensure(n > 0) { "Must be positive" }
return n
}
// Called inside either { }
val result = either { requirePositive(-1) } // Left("Must be positive")Gromadzenie błędów za pomocą zipOrAccumulate
Domyślnie Raise przerywa działanie po wystąpieniu pierwszego błędu. Należy użyć zipOrAccumulate(), aby wykonać wiele walidacji i zebrać wszystkie błędy w obiekcie NonEmptyList:
val result: Either<NonEmptyList<String>, User> = either {
zipOrAccumulate(
{ validateName(name).bind() },
{ validateAge(age).bind() }
) { validName, validAge -> User(validName, validAge) }
}recover { } — obsługa konkretnych błędów
Należy użyć recover { error -> ... } wewnątrz either { }, aby obsłużyć konkretny zgłoszony błąd, podać wartość zastępczą i wznowić obliczenia:
val name: String = either {
findUser(0L).bind().name
}.recover { error ->
if (error == UserError.NotFound) "Guest" else raise(error)
}.getOrNull() ?: "Guest"Raise a łączenie Either: kiedy używać poszczególnych rozwiązań
Należy użyć either { }.bind() w liniowych przepływach z wieloma sekwencyjnymi krokami — kod przypomina wtedy imperatywny, ale pozostaje czysty. Łączenie za pomocą flatMap sprawdzi się w krótkich, dwuetapowych kompozycjach lub podczas integracji z innymi bibliotekami funkcyjnymi.
Testowanie funkcji opartych na Raise
Należy wywołać funkcję wewnątrz either { } i sprawdzić wynik. Matchery Kotest shouldBeLeft() i shouldBeRight() biblioteki Arrow pozwalają zwięźle definiować asercje:
import arrow.core.shouldBeLeft
import arrow.core.shouldBeRight
@Test
fun `negative age returns Left`() {
validateAge(-1).shouldBeLeft()
}
@Test
fun `valid age returns Right`() {
validateAge(25).shouldBeRight(25)
}Szybkie sprawdzenie
Co dzieje się po wywołaniu .bind() na wartości Either.Left wewnątrz bloku either { }?
Podsumowanie: Raise DSL biblioteki Arrow
Najważniejsze informacje:
either { }tworzy obiektEitherna podstawie bloku z dostępnym kontekstemRaise.bind()rozpakowujeEitheri przerywa działanie po napotkaniuLeftensure(condition) { error }iensureNotNull(value) { error }służą do sprawdzania warunków w miejscu użyciazipOrAccumulate()służy do zbierania wielu błędów zamiast przerywania działania- Kod przypomina imperatywny, a jednocześnie pozostaje czysto funkcyjny
Często zadawane pytania
Czy lekcja „DSL Raise w Arrow: składanie typowanych błędów” jest bezpłatna?
Tak — pełny tekst „DSL Raise w Arrow: składanie typowanych błędów” 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 Kotlin Academy, przejdź na CoddyKit PRO. Kurs Kotlin Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „DSL Raise w Arrow: składanie typowanych błędów”?
Użyj kontekstu Raise w Arrow oraz raise(), aby przejrzyście składać przepływy z wieloma błędami. Ćwiczysz Kotlin Academy 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ąć Kotlin Academy?
Nie wymagamy żadnego doświadczenia. Kotlin Academy 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 2 z 4.
Ile czasu zajmuje lekcja „DSL Raise w Arrow: składanie typowanych błędów”?
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 Kotlin Academy?
Tak. Każda lekcja Kotlin Academy 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
- Either : typowana obsługa błędów bez wyjątków
- DSL Raise w Arrow: składanie typowanych błędów
- Option i nullable: kiedy używać każdego z nich
- Funkcjonalne modelowanie domeny za pomocą typów podstawowych Arrow