Either : essence, utilisation et principe de fonctionnement

Auteur : IT Sectr Publié le : 2026-05-26 Temps de lecture : 8 min

Either est un type fonctionnel qui représente une valeur parmi deux variantes possibles : Left pour les erreurs et Right pour le succès. Contrairement aux exceptions, Either rend la gestion d'erreurs explicite au niveau des types et ne nécessite pas de blocs try-catch. Selon Arrow, 2026, Either est largement utilisé dans les projets Kotlin pour composer des opérations susceptibles d'échouer, sans effets secondaires.

Points clés

  • Either est un type de données algébrique pour représenter deux variantes mutuellement exclusives : Left (erreur) et Right (succès).
  • Left contient traditionnellement les informations d'erreur, Right contient la valeur correcte.
  • Typage explicite — Either force la gestion des deux variantes à la compilation, éliminant les défaillances inattendues.
  • Composition — Either prend en charge map, flatMap et fold pour des chaînes de transformations sans vérifications imbriquées.
  • Différence avec Result — Either peut stocker un type d'erreur arbitraire, pas seulement Error ou Throwable.

Qu'est-ce qu'Either ?

Either est un type de données algébrique, emprunté à la programmation fonctionnelle, qui représente exactement un de deux types possibles. Dans le contexte de la gestion d'erreurs, la convention est la suivante : le type Left (Left) contient une description du problème, tandis que le type Right (Right) contient un résultat réussi.

Le concept d'Either provient du langage Haskell et de la catégorie de types Either a b, où a est le type de la valeur gauche et b celui de la valeur droite. Dans le développement mobile, Either a gagné en popularité grâce à la bibliothèque Arrow pour Kotlin et aux approches fonctionnelles en Swift.

L'avantage clé d'Either par rapport aux exceptions est l'absence de chemins d'exécution cachés. Une fonction qui retourne Either déclare explicitement dans sa signature qu'elle peut échouer. Le compilateur vérifie que les deux variantes sont traitées.

Contrairement au lancement d'exceptions, Either préserve la transparence du flux de données. Appeler une fonction qui retourne Either ne nécessite pas de try-catch du côté de l'appelant — le pattern-matching ou fold suffit. Ceci est particulièrement important dans les architectures à approche réactive, où chaque source de données retourne Either et les chaînes de transformation sont construites via map et flatMap.

Comment Either fonctionne : structure Left et Right

Either se compose de deux sous-types : Left et Right. Une instance d'Either ne peut être que l'un d'eux à tout moment. La signature typique en Kotlin est Either<E, A>, où E est le type d'erreur et A le type de valeur de succès.

Type Left : conteneur d'erreur

Left représente le cas d'échec. Contrairement aux exceptions, Left n'interrompt pas le flux d'exécution — il retourne simplement une valeur qui doit être traitée. Le type d'erreur peut être n'importe quoi : String, Int, une classe sealed personnalisée ou un modèle domaine.

Type Right : conteneur de succès

Right contient le résultat correct de l'opération. Le nom reflète la correction — par convention, Right signifie succès. Les transformations comme map et flatMap sont appliquées sur Right, permettant des chaînes de calcul sans vérifier chaque étape.

Composition d'Either avec flatMap

flatMap est le mécanisme principal de composition d'Either. Si la valeur actuelle est Right, flatMap applique la fonction passée et retourne un nouvel Either. Si c'est Left, flatMap ignore la transformation et propage l'erreur. Ce comportement est appelé évaluation de court-circuit.

En plus de flatMap, Either prend en charge mapLeft pour la transformation d'erreur, fold pour traiter les deux variantes en un seul endroit et getOrElse pour extraire une valeur avec une valeur par défaut. Ces fonctions couvrent tous les scénarios : de l'extraction simple à la composition complexe avec des appels asynchrones dans les coroutines Kotlin ou Combine en Swift.

kotlin
fun parseInt(input: String): Either<String, Int> =
    input.toIntOrNull()?.let { Right(it) }
    ?: Left("Échec de la conversion : $input")

fun divide(a: Int, b: Int): Either<String, Int> =
    if (b == 0) Left("Division par zéro")
    else Right(a / b)

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

Either en Kotlin : application pratique

Dans l'écosystème Kotlin, Either est implémenté dans la bibliothèque Arrow. La bibliothèque standard de Kotlin propose Result, mais Either offre plus de flexibilité : type d'erreur arbitraire, composition via flatMap et prise en charge des motifs fonctionnels.

Bibliothèque Arrow et Either

Arrow est une bibliothèque fonctionnelle pour Kotlin qui ajoute Either, Option, Validated et d'autres types. Arrow.Either est une classe sealed avec deux sous-classes : ArrowCore.Left et ArrowCore.Right. La bibliothèque fournit également des extensions pratiques : .getOrElse(), .fold(), .mapLeft().

Exemple : Either avec une requête réseau

Considérons un scénario réel — une requête réseau dans une application Android avec des erreurs possibles : absence de réseau, erreur serveur, réponse invalide. Either permet de combiner toutes les variantes en un seul type de retour.

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 : différence avec Result standard

En Swift, à partir de la version 5.0, le type intégré Result est disponible, conceptuellement similaire à Either mais avec des limitations : l'erreur doit être conforme au protocole Error et la valeur de succès doit être d'un seul type. Either en Swift est implémenté via une enum avec deux paramètres génériques.

Result standard vs. Either

Result<Success, Failure> est le type intégré de Swift, où Failure: Error. Either n'impose pas de contraintes sur le type d'erreur, permettant de stocker des String, des structures personnalisées ou même plusieurs types d'erreur via des enums imbriquées.

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 }

Quand utiliser Either dans les applications mobiles

Either est optimal pour les scénarios nécessitant une gestion d'erreurs explicite et type-safe sans exceptions. Examinons les principaux cas d'utilisation dans le développement mobile avec Kotlin et Swift.

  • Requêtes réseau — chaque requête peut retourner une erreur de connexion, de serveur ou d'analyse. Either regroupe toutes les variantes en un seul type.
  • Validation de formulaires — Either avec un type d'erreur personnalisé représente facilement le résultat de la validation des champs : e-mail ou mot de passe invalide.
  • Référentiel de données — Either permet de combiner les résultats de différentes sources (cache, BD, réseau) avec un type d'erreur unifié.
  • Interpréteur de commandes — si l'application analyse les entrées utilisateur ou les commandes, Either fournit une façon type-safe de signaler les erreurs.

N'utilisez pas Either pour des opérations simples sans effets secondaires — une valeur de retour normale est plus fiable et plus facile à lire. Either est également excessif lorsque l'échec est une situation exceptionnelle et non un scénario attendu.

Either est également efficace lorsqu'on travaille avec des coroutines en Kotlin. Une fonction qui retourne Either peut être appelée dans une coroutine avec une gestion d'erreurs via fold ou mapLeft sans bloquer le fil d'exécution. Ceci est particulièrement utile dans les applications Android avec une architecture MVVM, où chaque référentiel retourne Either et le ViewModel transforme le résultat en UiState.

Erreurs courantes lors de l'utilisation d'Either

Les développeurs qui découvrent Either commettent souvent des erreurs similaires. Examinons les plus courantes et comment les éviter.

  • Ignorer Left — appeler .getOrElse() avec une valeur par défaut sans analyser la cause de l'erreur vide de sens l'utilisation d'Either. Traitez l'erreur explicitement.
  • Type d'erreur global — utiliser String ou Exception comme type commun pour tous les Either dans un projet réduit la sécurité des types. Créez des classes sealed de domaine.
  • Either imbriqués — un Either dans Right (Either<E, Either<E, A>>) complique la lecture. Utilisez flatMap pour aplatir.
  • Mélange avec des exceptions — une fonction retourne Either mais lance des exceptions en interne. Cela contredit l'idée de gestion explicite des erreurs.

Foire aux questions

Quelle est la différence entre Either et Optional ?

Optional représente la présence ou l'absence d'une valeur (Some/None), mais n'indique pas la cause de l'absence. Either fournit deux types concrets — gauche pour l'erreur et droit pour le succès — permettant de transmettre le contexte de l'échec.

Peut-on utiliser Either en Java ?

En Java, il n'y a pas d'Either intégré, mais les bibliothèques Vavr et functionaljava fournissent des implémentations. Dans le développement Android, Either de Vavr est une alternative populaire pour un style fonctionnel avec des lambdas.

Quand utiliser sealed class plutôt qu'Either ?

Sealed class en Kotlin est plus pratique lorsqu'il y a plus de deux variantes ou qu'elles ont des structures différentes. Pour un résultat binaire (erreur/succès), Either est plus compact et fournit des combinateurs fonctionnels prêts à l'emploi.

Either prend-il en charge le multithreading ?

Either est immuable et thread-safe par défaut. En Kotlin avec les coroutines, Either se combine parfaitement : flatMap fonctionne dans un scope de coroutine et la gestion d'erreurs ne nécessite pas de verrous.

Dois-je utiliser Either pour toutes les fonctions du projet ?

Non. Either convient aux opérations avec des échecs attendus (réseau, validation, logique métier). Pour les getters simples et les calculs sans effets secondaires, un type normal se lit plus facilement et n'ajoute pas de complexité inutile.

Résumé

  • Either est un type fonctionnel pour représenter deux variantes : Left (erreur) et Right (succès), rendant la gestion d'erreurs explicite au niveau des types.
  • Left peut contenir un type d'erreur arbitraire — de String à une classe sealed de domaine, contrairement au Result standard.
  • flatMap permet la composition d'Either sans vérifications imbriquées : l'erreur se propage automatiquement dans toute la chaîne.
  • Arrow est la bibliothèque principale d'Either pour Kotlin avec prise en charge intégrée des coroutines et des extensions.
  • Swift utilise le Result intégré, mais Either peut être implémenté via une enum avec deux paramètres génériques pour une flexibilité maximale.
  • Utilisez Either pour les requêtes réseau, la validation de formulaires et les référentiels — les scénarios avec des erreurs attendues.
  • Évitez les types d'erreur globaux, l'ignorance de Left et les Either imbriqués — cela réduit les avantages de la sécurité des types.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi