DSL Raise do Arrow: composição de erros tipados
Use o contexto Raise do Arrow e raise() para compor fluxos com vários erros de forma clara.
DSL Raise do Arrow: composição de erros tipados é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.
A limitação do encadeamento de Either
Encadear Either com flatMap cria lambdas profundamente aninhadas quando há várias operações sequenciais. A DSL Raise do Arrow (introduzida no Arrow 1.2) oferece uma sintaxe mais limpa, no estilo de corrotinas, usando receptores de contexto ou funções de extensão do Kotlin.
O que é Raise<E>?
Raise é um contexto que pode emitir (interromper antecipadamente com) um erro do tipo E. Uma função que pode falhar chama raise(error) para abortar e propagar o erro, de forma semelhante a lançar uma exceção, mas sem exceções.
O construtor either { }
O construtor either { } cria um Either a partir de um bloco que tem um Raise disponível no escopo. Dentro dele, use raise(error) em caso de falha ou simplesmente retorne um valor em caso de sucesso:
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() — Desempacotando Either dentro de either{}
Dentro de um bloco either { }, chame .bind() em qualquer valor Either para desempacotá-lo. Se for um Left, bind() emite automaticamente o erro e interrompe o bloco:
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() — Verificação de condição em linha
ensure(condition) { error } é uma forma abreviada de if (!condition) raise(error). Isso mantém a lógica de validação concisa:
fun validateEmail(email: String): Either<String, String> = either {
ensure(email.contains("@")) { "Email must contain @" }
ensure(email.length <= 255) { "Email too long" }
email
}ensureNotNull() — Verificação de nulo com Raise
ensureNotNull(value) { error } desempacota um valor anulável ou emite um erro se ele for nulo:
fun findUser(id: Long, repo: UserRepo): Either<UserError, User> = either {
ensureNotNull(repo.findById(id)) { UserError.NotFound(id) }
}Raise com receptores de contexto (Arrow 1.2+)
Você pode declarar diretamente funções que exigem um contexto Raise, sem encapsulá-las em 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")Acumulando erros com zipOrAccumulate
Por padrão, Raise interrompe a execução no primeiro erro. Use zipOrAccumulate() para executar várias validações e coletar todos os erros em uma NonEmptyList:
val result: Either<NonEmptyList<String>, User> = either {
zipOrAccumulate(
{ validateName(name).bind() },
{ validateAge(age).bind() }
) { validName, validAge -> User(validName, validAge) }
}recover { } — Tratando erros específicos
Use recover { error -> ... } dentro de either { } para tratar um erro emitido específico e fornecer um valor alternativo, retomando o cálculo:
val name: String = either {
findUser(0L).bind().name
}.recover { error ->
if (error == UserError.NotFound) "Guest" else raise(error)
}.getOrNull() ?: "Guest"Raise vs. encadeamento de Either: quando usar cada um
Use either { }.bind() para fluxos lineares com várias etapas sequenciais — a leitura é semelhante à de código imperativo, mas o código continua puro. Use o encadeamento com flatMap para composições curtas de duas etapas ou ao compor com outras bibliotecas funcionais.
Testando funções baseadas em Raise
Teste chamando a função dentro de either { } e fazendo uma asserção sobre o resultado. Os matchers do Kotest shouldBeLeft() e shouldBeRight() do Arrow tornam as asserções concisas:
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ção rápida
Dentro de um bloco either { }, o que acontece ao chamar .bind() em um valor Either.Left?
Recapitulação: DSL Raise do Arrow
Principais conclusões:
either { }cria umEithera partir de um bloco comRaisedisponível no escopo.bind()desempacotaEithere interrompe a execução ao encontrar umLeftensure(condition) { error }eensureNotNull(value) { error }servem para verificações em linhazipOrAccumulate()coleta vários erros em vez de interromper a execução- Tem a aparência de código imperativo, embora permaneça puramente funcional
Perguntas Frequentes
A aula “DSL Raise do Arrow: composição de erros tipados” é grátis?
Sim — o texto completo de “DSL Raise do Arrow: composição de erros tipados” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.
O que vou aprender em “DSL Raise do Arrow: composição de erros tipados”?
Use o contexto Raise do Arrow e raise() para compor fluxos com vários erros de forma clara. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Kotlin Academy?
Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.
Quanto tempo leva a aula “DSL Raise do Arrow: composição de erros tipados”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Kotlin Academy?
Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Either : tratamento de erros tipado sem exceções
- DSL Raise do Arrow: composição de erros tipados
- Option e Nullable: quando usar cada um
- Modelagem funcional de domínios com os tipos centrais do Arrow