0Pricing
Kotlin Academy · Aula

Modelagem funcional de domínios com os tipos centrais do Arrow

Modele domínios complexos usando Either, NonEmptyList e acumulação de erros validados.

Modelagem funcional de domínios com os tipos centrais do Arrow é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 4 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.

O que é modelagem funcional de domínio

A modelagem funcional de domínio usa tipos algébricos (Either, Option, classes seladas) para codificar regras de negócio nos tipos. Estados inválidos tornam-se impossíveis de representar em tempo de compilação, e os erros ficam explícitos nas assinaturas das funções — sem exceções ocultas.

Objetos de valor com classes inline/de valor

Use classes de valor do Kotlin para encapsular tipos primitivos e evitar a obsessão por tipos primitivos. O sistema de tipos rejeita passar um UserId onde se espera um PostId:

@JvmInline value class UserId(val value: Long)
@JvmInline value class PostId(val value: Long)

fun findUser(id: UserId): Either<UserError, User> = TODO()
// findUser(PostId(1L))  // Compile error!

Classes seladas para erros de domínio

Modele os erros como hierarquias de classes seladas. Cada subclasse contém apenas os dados relevantes para aquele caso de erro:

sealed class UserError {
    data class NotFound(val id: UserId) : UserError()
    data class EmailTaken(val email: String) : UserError()
    data class ValidationFailed(val field: String, val reason: String) : UserError()
}

Validated: acumulando vários erros

Quando quiser relatar todos os erros de validação de uma só vez, e não apenas o primeiro, use Validated do Arrow (ou zipOrAccumulate na DSL Raise). Ele acumula os erros em uma NonEmptyList:

import arrow.core.Validated
import arrow.core.valid
import arrow.core.invalid

fun validateName(name: String): Validated<String, String> =
    if (name.isNotBlank()) name.valid() else "Name is blank".invalid()

Compondo validações

Use zip() para combinar vários resultados Validated. Se algum deles for Invalid, todos os erros serão acumulados:

val result: Validated<NonEmptyList<String>, User> =
    validateName(name).zip(validateEmail(email)) { n, e -> User(n, e) }
        .mapLeft { it }

Tornando estados ilegais impossíveis de representar

Em vez de usar um User com um email anulável e um sinalizador isVerified, use subclasses seladas para que o sistema de tipos impeça o acesso ao e-mail de um usuário não verificado:

sealed class User {
    data class Unverified(val id: UserId, val pendingEmail: String) : User()
    data class Verified(val id: UserId, val email: String) : User()
}

Construtores inteligentes

Use funções de fábrica do objeto companheiro que retornem Either ou Option, em vez de construtores públicos. Isso garante que as instâncias estejam sempre em um estado válido:

class Email private constructor(val value: String) {
    companion object {
        fun of(raw: String): Either<String, Email> =
            if (raw.contains("@") && raw.length <= 255) Email(raw).right()
            else "Invalid email format".left()
    }
}

Combinando Either e opção em uma cadeia

Uma operação de domínio real normalmente encadeia consultas a repositórios (Option) com validações (Either). Use o bloco either { } do Arrow com .bind() para compô-las de forma fluida:

fun createPost(authorId: UserId, title: String, body: String): Either<PostError, Post> = either {
    val author = userRepo.findById(authorId).toEither { PostError.AuthorNotFound }.bind()
    val validTitle = validateTitle(title).bind()
    postRepo.save(Post(author, validTitle, body))
}

Imutabilidade e cópia

As entidades de domínio devem ser imutáveis. Use classes de dados e copy() para derivar novos estados. O Lens do Arrow (de arrow-optics) permite atualizações aninhadas práticas sem mutação:

val updated = user.copy(email = "new@example.com")
// Arrow Optics:
val emailLens = User.email
val updatedWithLens = emailLens.set(user, "new@example.com")

Configuração com segurança de tipos usando classes seladas

Modele as variantes de configuração da aplicação com classes seladas para que o compilador obrigue você a tratar cada caso:

sealed class DbConfig {
    data class Postgres(val url: String, val user: String, val pass: String) : DbConfig()
    data class InMemory(val dbName: String = "test") : DbConfig()
}

Benefícios em resumo

A modelagem funcional de domínio com os tipos fundamentais do Arrow oferece:

  • Nenhuma exceção de ponteiro nulo no código de domínio
  • Erros visíveis nas assinaturas das funções
  • Verificações exaustivas de when nas hierarquias seladas
  • Funções puras fáceis de testar
  • Código autodocumentado

Verificação rápida

Qual é o principal benefício de usar uma hierarquia de sealed class para erros de domínio em vez de lançar exceções?

Recapitulação: modelagem funcional de domínio com os tipos fundamentais do Arrow

Principais aprendizados:

  • Classes de valor evitam a obsessão por tipos primitivos
  • Hierarquias seladas de erros tornam os casos de falha exaustivos e seguros quanto aos tipos
  • Construtores inteligentes garantem instâncias válidas
  • either { }.bind() compõe operações sujeitas a falha de forma limpa
  • Dados imutáveis + copy() / Arrow Optics para transições de estado seguras

Perguntas Frequentes

A aula “Modelagem funcional de domínios com os tipos centrais do Arrow” é grátis?

Sim — o texto completo de “Modelagem funcional de domínios com os tipos centrais do Arrow” é 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 “Modelagem funcional de domínios com os tipos centrais do Arrow”?

Modele domínios complexos usando Either, NonEmptyList e acumulação de erros validados. 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 4 de 4.

Quanto tempo leva a aula “Modelagem funcional de domínios com os tipos centrais do Arrow”?

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