DSL Raise di Arrow: composizione degli errori tipizzati
Utilizzi il contesto Raise di Arrow e raise() per comporre in modo chiaro flussi con più errori.
DSL Raise di Arrow: composizione degli errori tipizzati è una lezione Kotlin Academy gratuita su CoddyKit. Questa è la lezione 2 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 Kotlin Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Kotlin Academy include 4 lezioni in totale.
Il limite del concatenamento di Either
Concatenare Either con flatMap crea lambda profondamente annidate quando sono presenti più operazioni sequenziali. Il Raise DSL di Arrow (introdotto in Arrow 1.2) offre una sintassi più pulita, in stile coroutine, utilizzando i context receiver o le funzioni di estensione di Kotlin.
Che cos'è Raise<E>?
Raise è un contesto che può sollevare (interrompendo il flusso con) un errore di tipo E. Una funzione che può fallire chiama raise(error) per interrompere ed effettuare la propagazione dell'errore, in modo simile al lancio di un'eccezione ma senza usare eccezioni.
Il builder either { }
Il builder either { } crea un Either a partire da un blocco che ha un Raise nello scope. Al suo interno, invochi raise(error) in caso di errore oppure restituisca semplicemente un valore in caso di successo:
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() — estrarre Either all'interno di either{}
All'interno di un blocco either { }, chiami .bind() su qualsiasi valore Either per estrarlo. Se il valore è un Left, bind() esegue automaticamente il raise e interrompe il blocco:
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() — controllo inline di una condizione
ensure(condition) { error } è una forma abbreviata di if (!condition) raise(error). Mantiene concisa la logica di validazione:
fun validateEmail(email: String): Either<String, String> = either {
ensure(email.contains("@")) { "Email must contain @" }
ensure(email.length <= 255) { "Email too long" }
email
}ensureNotNull() — controllo dei valori null con Raise
ensureNotNull(value) { error } estrae un valore nullable oppure esegue il raise se il valore è null:
fun findUser(id: Long, repo: UserRepo): Either<UserError, User> = either {
ensureNotNull(repo.findById(id)) { UserError.NotFound(id) }
}Raise con context receiver (Arrow 1.2+)
È possibile dichiarare direttamente funzioni che richiedono un contesto Raise, senza racchiuderle in 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")Aggregazione degli errori con zipOrAccumulate
Per impostazione predefinita, Raise interrompe il flusso al primo errore. Utilizzi zipOrAccumulate() per eseguire più validazioni e raccogliere tutti gli errori in una NonEmptyList:
val result: Either<NonEmptyList<String>, User> = either {
zipOrAccumulate(
{ validateName(name).bind() },
{ validateAge(age).bind() }
) { validName, validAge -> User(validName, validAge) }
}recover { } — gestione di errori specifici
Utilizzi recover { error -> ... } all'interno di either { } per gestire un errore sollevato specifico e fornire un valore di fallback, riprendendo il calcolo:
val name: String = either {
findUser(0L).bind().name
}.recover { error ->
if (error == UserError.NotFound) "Guest" else raise(error)
}.getOrNull() ?: "Guest"Raise e concatenamento di Either: quando usare ciascuno
Utilizzi either { }.bind() per flussi lineari con più passaggi sequenziali: il codice viene letto come codice imperativo, ma rimane puro. Utilizzi il concatenamento con flatMap per brevi composizioni di due passaggi o quando si integra con altre librerie funzionali.
Testare le funzioni basate su Raise
Esegua il test chiamando la funzione all'interno di either { } e verificando il risultato. I matcher Kotest shouldBeLeft() e shouldBeRight() di Arrow rendono concise le asserzioni:
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)
}Verifica rapida
All'interno di un blocco either { }, che cosa accade chiamando .bind() su un valore Either.Left?
Riepilogo: Raise DSL di Arrow
Punti chiave:
either { }crea unEithera partire da un blocco conRaisenello scope.bind()estrae il valore daEithere interrompe il flusso in caso diLeftensure(condition) { error }eensureNotNull(value) { error }per i controlli inlinezipOrAccumulate()raccoglie più errori invece di interrompere il flusso al primo- Il codice viene letto come codice imperativo, pur rimanendo puramente funzionale
Domande Frequenti
La lezione «DSL Raise di Arrow: composizione degli errori tipizzati» è gratuita?
Sì — il testo completo di «DSL Raise di Arrow: composizione degli errori tipizzati» è 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 Kotlin Academy, passa a CoddyKit PRO. Il corso Kotlin Academy include 4 lezioni in totale.
Cosa imparerò in «DSL Raise di Arrow: composizione degli errori tipizzati»?
Utilizzi il contesto Raise di Arrow e raise() per comporre in modo chiaro flussi con più errori. Eserciti Kotlin Academy 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 Kotlin Academy?
Non è richiesta alcuna esperienza precedente. Kotlin Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.
Quanto tempo richiede la lezione «DSL Raise di Arrow: composizione degli errori tipizzati»?
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 Kotlin Academy?
Sì. Ogni lezione Kotlin Academy 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
- Either : gestione tipizzata degli errori senza eccezioni
- DSL Raise di Arrow: composizione degli errori tipizzati
- Option e nullable: quando utilizzare ciascuno
- Modellazione funzionale del dominio con i tipi fondamentali di Arrow