Either: qué es, cómo funciona y aplicación práctica

Autor: IT Sectr Publicado: 2026-05-26 Tiempo de lectura: 8 min

Either es un tipo funcional que representa un valor de una de dos variantes posibles: Left para errores y Right para éxito. A diferencia de las excepciones, Either hace que el manejo de errores sea explícito a nivel de tipos y no requiere bloques try-catch. Según Arrow, 2026, Either se utiliza ampliamente en proyectos Kotlin para componer operaciones que pueden fallar, sin efectos secundarios.

Puntos clave

  • Either es un tipo de dato algebraico para representar dos variantes mutuamente excluyentes: Left (error) y Right (éxito).
  • Left tradicionalmente contiene información del error, Right contiene el valor correcto.
  • Tipificación explícita — Either obliga a manejar ambas variantes en tiempo de compilación, eliminando fallos inesperados.
  • Composición — Either admite map, flatMap y fold para cadenas de transformaciones sin comprobaciones anidadas.
  • Diferencia con Result — Either puede almacenar un tipo de error arbitrario, no solo Error o Throwable.

¿Qué es Either?

Either es un tipo de dato algebraico, tomado de la programación funcional, que representa exactamente uno de dos tipos posibles. En el contexto del manejo de errores, la convención es: el tipo Left (Left) contiene una descripción del problema, mientras que el tipo Right (Right) contiene un resultado exitoso.

El concepto de Either proviene del lenguaje Haskell y la categoría de tipos Either a b, donde a es el tipo del valor izquierdo y b el del derecho. En el desarrollo móvil, Either ganó popularidad gracias a la biblioteca Arrow para Kotlin y los enfoques funcionales en Swift.

La ventaja clave de Either sobre las excepciones es la ausencia de rutas de ejecución ocultas. Una función que devuelve Either declara explícitamente en su firma que puede fallar. El compilador garantiza que ambas variantes sean manejadas.

A diferencia de lanzar excepciones, Either preserva la transparencia del flujo de datos. Llamar a una función que devuelve Either no requiere try-catch del lado del llamante — basta con pattern-matching o fold. Esto es especialmente importante en arquitecturas con enfoque reactivo, donde cada fuente de datos devuelve Either y las cadenas de transformación se construyen con map y flatMap.

Cómo funciona Either: estructura Left y Right

Either consta de dos subtipos: Left y Right. Una instancia de Either solo puede ser uno de ellos en cada momento. La firma típica en Kotlin es Either<E, A>, donde E es el tipo de error y A el tipo de valor exitoso.

Tipo Left: contenedor de error

Left representa el caso de fallo. A diferencia de las excepciones, Left no interrumpe el flujo de ejecución — simplemente devuelve un valor que debe ser manejado. El tipo de error puede ser cualquiera: String, Int, una clase sellada personalizada o un modelo de dominio.

Tipo Right: contenedor de éxito

Right contiene el resultado correcto de la operación. El nombre refleja la corrección — por convención, Right significa éxito. Las transformaciones map y flatMap se aplican sobre Right, permitiendo cadenas de cálculos sin verificar cada paso.

Composición de Either mediante flatMap

flatMap es el mecanismo principal de composición de Either. Si el valor actual es Right, flatMap aplica la función recibida y devuelve un nuevo Either. Si es Left, flatMap omite la transformación y propaga el error. Este comportamiento se denomina evaluación de cortocircuito.

Además de flatMap, Either admite mapLeft para transformar el error, fold para manejar ambas variantes en un solo lugar y getOrElse para extraer un valor con un valor predeterminado. Estas funciones cubren todos los escenarios: desde la extracción simple hasta la composición compleja con llamadas asíncronas en corrutinas de Kotlin o Combine en Swift.

kotlin
fun parseInt(input: String): Either<String, Int> =
    input.toIntOrNull()?.let { Right(it) }
    ?: Left("No se pudo convertir: $input")

fun divide(a: Int, b: Int): Either<String, Int> =
    if (b == 0) Left("División por cero")
    else Right(a / b)

val result = parseInt("10")
    .flatMap { divide(it, 2) }

Either en Kotlin: aplicación práctica

En el ecosistema Kotlin, Either está implementado en la biblioteca Arrow. La biblioteca estándar de Kotlin ofrece Result, pero Either proporciona más flexibilidad: tipo de error arbitrario, composición mediante flatMap y soporte para patrones funcionales.

Biblioteca Arrow y Either

Arrow es una biblioteca funcional para Kotlin que añade Either, Option, Validated y otros tipos. Arrow.Either es una clase sellada con dos subclases: ArrowCore.Left y ArrowCore.Right. La biblioteca también proporciona extensiones convenientes: .getOrElse(), .fold(), .mapLeft().

Ejemplo: Either con petición de red

Consideremos un escenario real — una petición de red en una aplicación Android con posibles errores: falta de red, error del servidor, respuesta incorrecta. Either permite combinar todas las variantes en un único tipo de retorno.

kotlin
sealed class NetworkError {
    data class NoConnection(val message: String): NetworkError()
    data class ServerError(val code: Int): NetworkError()
    data class ParseError(val detail: String): NetworkError()
}

suspend fun fetchUser(id: String): Either<NetworkError, User> {
    return try {
        val response = api.getUser(id)
        if (response.isSuccessful) {
            Right(response.body()!!)
        } else {
            Left(NetworkError.ServerError(response.code()))
        }
    } catch (e: IOException) {
        Left(NetworkError.NoConnection(e.message ?: ""))
    }
}

Either en Swift: diferencia con Result estándar

En Swift, a partir de la versión 5.0, está disponible el tipo integrado Result, conceptualmente similar a Either pero con limitaciones: el error debe cumplir el protocolo Error y el valor de éxito debe ser de un único tipo. Either en Swift se implementa mediante un enum con dos parámetros genéricos.

Result estándar vs. Either

Result<Success, Failure> es el tipo integrado de Swift, donde Failure: Error. Either no impone restricciones sobre el tipo de error, lo que permite almacenar String, estructuras personalizadas o incluso múltiples tipos de error mediante enums anidados.

swift
enum Either<E, A> {
    case left(E)
    case right(A)

    func map<B>(_ transform: (A) -> B) -> Either<E, B> {
        switch self {
        case .left(let e): return .left(e)
        case .right(let a): return .right(transform(a))
        }
    }
}

let result: Either<String, Int> = .right(42)
let mapped = result.map { $0 * 2 }

Cuándo usar Either en aplicaciones móviles

Either es óptimo para escenarios que requieren manejo de errores explícito y type-safe sin excepciones. Consideremos los casos principales de uso en desarrollo móvil con Kotlin y Swift.

  • Peticiones de red — cada petición puede devolver un error de conexión, de servidor o de análisis. Either agrupa todas las variantes en un solo tipo.
  • Validación de formularios — Either con un tipo de error personalizado representa cómodamente el resultado de la validación de campos: email o contraseña no válidos.
  • Repositorio de datos — Either permite combinar resultados de diferentes fuentes (caché, BD, red) con un tipo de error unificado.
  • Intérprete de comandos — si la aplicación analiza entrada de usuario o comandos, Either proporciona una forma type-safe de notificar errores.

No uses Either para operaciones simples sin efectos secundarios — un valor de retorno normal es más fiable y fácil de leer. Either también es excesivo cuando el fallo es una situación excepcional y no un escenario esperado.

Either también es eficaz al trabajar con corrutinas en Kotlin. Una función que devuelve Either puede llamarse dentro de una corrutina con manejo de errores mediante fold o mapLeft sin bloquear el hilo. Esto es especialmente útil en aplicaciones Android con arquitectura MVVM, donde cada repositorio devuelve Either y la ViewModel transforma el resultado en UiState.

Errores típicos al trabajar con Either

Los desarrolladores que se familiarizan por primera vez con Either suelen cometer errores similares. Examinemos los más comunes y cómo evitarlos.

  • Ignorar Left — llamar a .getOrElse() con un valor por defecto sin analizar la causa del error pierde el sentido de usar Either. Maneja el error explícitamente.
  • Tipo de error global — usar String o Exception como tipo común para todos los Either en un proyecto reduce la seguridad de tipos. Crea clases selladas de dominio.
  • Either anidados — un Either dentro de Right (Either<E, Either<E, A>>) dificulta la lectura. Usa flatMap para aplanar.
  • Mezcla con excepciones — una función devuelve Either pero internamente lanza excepciones. Esto contradice la idea del manejo explícito de errores.

Preguntas frecuentes

¿En qué se diferencia Either de Optional?

Optional representa la presencia o ausencia de un valor (Some/None), pero no informa la causa de la ausencia. Either proporciona dos tipos concretos — izquierdo para error y derecho para éxito — lo que permite transmitir el contexto del fallo.

¿Se puede usar Either en Java?

En Java no hay Either incorporado, pero las bibliotecas Vavr y functionaljava proporcionan implementaciones. En desarrollo Android, Either de Vavr es una alternativa popular para un estilo funcional con lambdas.

¿Cuándo es mejor usar sealed class en lugar de Either?

Sealed class en Kotlin es más conveniente cuando hay más de dos variantes o tienen estructuras diferentes. Para un resultado binario (error/éxito), Either es más compacto y proporciona combinadores funcionales listos para usar.

¿Either admite multitarea?

Either es inmutable y seguro para hilos por defecto. En Kotlin con corrutinas, Either se combina perfectamente: flatMap funciona dentro de un ámbito de corrutina y el manejo de errores no requiere bloqueos.

¿Debería usar Either para todas las funciones del proyecto?

No. Either es adecuado para operaciones con fallos esperados (red, validación, lógica de negocio). Para getters simples y cálculos sin efectos secundarios, un tipo normal se lee más fácilmente y no añade complejidad innecesaria.

Resumen

  • Either es un tipo funcional para representar dos variantes: Left (error) y Right (éxito), haciendo explícito el manejo de errores a nivel de tipos.
  • Left puede contener un tipo de error arbitrario — desde String hasta una clase sellada de dominio, a diferencia de Result estándar.
  • flatMap permite la composición de Either sin comprobaciones anidadas: el error se propaga automáticamente por toda la cadena.
  • Arrow es la biblioteca principal de Either para Kotlin con soporte integrado de corrutinas y extensiones.
  • Swift usa Result integrado, pero Either puede implementarse mediante un enum con dos parámetros genéricos para máxima flexibilidad.
  • Usa Either para peticiones de red, validación de formularios y repositorios — escenarios con errores esperados.
  • Evita tipos de error globales, ignorar Left y Either anidados — esto reduce los beneficios de la seguridad de tipos.

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también