0Pricing
Kotlin Academy · Aula

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 um Either a partir de um bloco com Raise disponível no escopo
  • .bind() desempacota Either e interrompe a execução ao encontrar um Left
  • ensure(condition) { error } e ensureNotNull(value) { error } servem para verificações em linha
  • zipOrAccumulate() 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

  1. Either : tratamento de erros tipado sem exceções
  2. DSL Raise do Arrow: composição de erros tipados
  3. Option e Nullable: quando usar cada um
  4. Modelagem funcional de domínios com os tipos centrais do Arrow
← Voltar para Kotlin Academy