Either: Wesen, Anwendung und Funktionsweise

Autor: IT Sectr Veröffentlicht: 2026-05-26 Lesezeit: 8 Min.

Either ist ein funktionaler Typ, der einen Wert von zwei möglichen Varianten darstellt: Left für Fehler und Right für Erfolg. Im Gegensatz zu Ausnahmen macht Either die Fehlerbehandlung auf Typebene explizit und erfordert keine try-catch-Blöcke. Laut Arrow, 2026 wird Either in Kotlin-Projekten weit verbreitet eingesetzt, um Operationen zu komponieren, die ohne Nebenwirkungen fehlschlagen können.

Wichtige Punkte

  • Either ist ein algebraischer Datentyp zur Darstellung von zwei sich gegenseitig ausschließenden Varianten: Left (Fehler) und Right (Erfolg).
  • Left enthält traditionell die Fehlerinformationen, Right den korrekten Wert.
  • Explizite Typisierung — Either zwingt zur Behandlung beider Varianten zur Compile-Zeit und vermeidet unerwartete Ausfälle.
  • Komposition — Either unterstützt map, flatMap und fold für Transformationsketten ohne verschachtelte Prüfungen.
  • Unterschied zu Result — Either kann einen beliebigen Fehlertyp speichern, nicht nur Error oder Throwable.

Was ist Either?

Either ist ein algebraischer Datentyp, der aus der funktionalen Programmierung stammt und genau einen von zwei möglichen Typen darstellt. Im Kontext der Fehlerbehandlung gilt die Konvention: Der Left-Typ (Left) enthält eine Problembeschreibung, während der Right-Typ (Right) ein erfolgreiches Ergebnis enthält.

Das Konzept von Either stammt aus der Sprache Haskell und der Typkategorie Either a b, wobei a der Typ des linken Werts und b der Typ des rechten Werts ist. In der mobilen Entwicklung gewann Either durch die Arrow-Bibliothek für Kotlin und funktionale Ansätze in Swift an Popularität.

Der Hauptvorteil von Either gegenüber Ausnahmen ist das Fehlen versteckter Ausführungspfade. Eine Funktion, die Either zurückgibt, deklariert explizit in ihrer Signatur, dass sie fehlschlagen kann. Der Compiler stellt sicher, dass beide Varianten behandelt werden.

Im Gegensatz zum Werfen von Ausnahmen bewahrt Either die Transparenz des Datenflusses. Der Aufruf einer Funktion, die Either zurückgibt, erfordert auf der Aufruferseite kein try-catch — pattern-matching oder fold reichen aus. Dies ist besonders wichtig in Architekturen mit reaktivem Ansatz, bei denen jede Datenquelle Either zurückgibt und Transformationsketten über map und flatMap aufgebaut werden.

Wie Either funktioniert: Left- und Right-Struktur

Either besteht aus zwei Subtypen: Left und Right. Eine Either-Instanz kann zu jedem Zeitpunkt nur einer von ihnen sein. Die typische Signatur in Kotlin ist Either<E, A>, wobei E der Fehlertyp und A der Typ des Erfolgswerts ist.

Left-Typ: Fehlercontainer

Left stellt den Fehlerfall dar. Anders als Ausnahmen unterbricht Left nicht den Ausführungsfluss — es gibt lediglich einen Wert zurück, der behandelt werden muss. Der Fehlertyp kann beliebig sein: String, Int, eine benutzerdefinierte versiegelte Klasse oder ein Domänenmodell.

Right-Typ: Erfolgscontainer

Right enthält das korrekte Ergebnis der Operation. Der Name spiegelt die Korrektheit wider — per Konvention bedeutet Right Erfolg. Transformationen wie map und flatMap werden auf Right angewendet, was Berechnungsketten ohne Überprüfung jedes Schritts ermöglicht.

Komposition von Either mit flatMap

flatMap ist der Hauptmechanismus zur Komposition von Either. Wenn der aktuelle Wert Right ist, wendet flatMap die übergebene Funktion an und gibt ein neues Either zurück. Bei Left überspringt flatMap die Transformation und gibt den Fehler weiter. Dieses Verhalten wird als Kurzschlussauswertung bezeichnet.

Neben flatMap unterstützt Either mapLeft zur Fehlertransformation, fold zur Behandlung beider Varianten an einer Stelle und getOrElse zum Extrahieren eines Werts mit einem Standardwert. Diese Funktionen decken alle Szenarien ab: von der einfachen Extraktion bis zur komplexen Komposition mit asynchronen Aufrufen in Kotlin-Koroutinen oder Swift Combine.

kotlin
fun parseInt(input: String): Either<String, Int> =
    input.toIntOrNull()?.let { Right(it) }
    ?: Left("Konnte nicht konvertiert werden: $input")

fun divide(a: Int, b: Int): Either<String, Int> =
    if (b == 0) Left("Division durch Null")
    else Right(a / b)

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

Either in Kotlin: praktische Anwendung

Im Kotlin-Ökosystem ist Either in der Arrow-Bibliothek implementiert. Die Kotlin-Standardbibliothek bietet Result, aber Either bietet mehr Flexibilität: beliebiger Fehlertyp, Komposition über flatMap und Unterstützung funktionaler Muster.

Arrow-Bibliothek und Either

Arrow ist eine funktionale Bibliothek für Kotlin, die Either, Option, Validated und andere Typen hinzufügt. Arrow.Either ist eine versiegelte Klasse mit zwei Unterklassen: ArrowCore.Left und ArrowCore.Right. Die Bibliothek bietet auch praktische Erweiterungen: .getOrElse(), .fold(), .mapLeft().

Beispiel: Either mit einer Netzwerkanfrage

Betrachten wir ein reales Szenario — eine Netzwerkanfrage in einer Android-App mit möglichen Fehlern: keine Netzwerkverbindung, Serverfehler, ungültige Antwort. Either ermöglicht es, alle Varianten in einem einzigen Rückgabetyp zu kombinieren.

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 in Swift: Unterschied zum standardmäßigen Result

In Swift ist ab Version 5.0 der integrierte Result-Typ verfügbar, der konzeptionell Either ähnelt, aber Einschränkungen hat: Der Fehler muss dem Error-Protokoll entsprechen, und der Erfolgswert muss von einem einzigen Typ sein. Either in Swift wird mit einem enum mit zwei generischen Parametern implementiert.

Standard-Result vs. Either

Result<Success, Failure> ist der integrierte Typ von Swift, wobei Failure: Error. Either erzwingt keine Einschränkungen für den Fehlertyp und kann String, benutzerdefinierte Strukturen oder sogar mehrere Fehlertypen über verschachtelte Enums speichern.

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 }

Wann man Either in mobilen Apps verwendet

Either ist optimal für Szenarien, die eine explizite und typsichere Fehlerbehandlung ohne Ausnahmen erfordern. Betrachten wir die wichtigsten Anwendungsfälle in der mobilen Entwicklung mit Kotlin und Swift.

  • Netzwerkanfragen — jede Anfrage kann einen Verbindungsfehler, Serverfehler oder Parsing-Fehler zurückgeben. Either fasst alle Varianten in einem Typ zusammen.
  • Formularvalidierung — Either mit einem benutzerdefinierten Fehlertyp stellt praktisch das Ergebnis der Eingabefeldvalidierung dar: ungültige E-Mail oder Passwort.
  • Daten-Repository — Either ermöglicht die Kombination von Ergebnissen aus verschiedenen Quellen (Cache, DB, Netzwerk) mit einem einheitlichen Fehlertyp.
  • Befehlsinterpreter — wenn eine App Benutzereingaben oder Befehle analysiert, bietet Either eine typsichere Möglichkeit, Fehler zu melden.

Verwenden Sie Either nicht für einfache Operationen ohne Nebenwirkungen — ein normaler Rückgabewert ist zuverlässiger und leichter lesbar. Either ist auch überflüssig, wenn ein Fehler eine Ausnahmesituation und kein erwartetes Szenario ist.

Either ist auch bei der Arbeit mit Koroutinen in Kotlin effektiv. Eine Funktion, die Either zurückgibt, kann innerhalb einer Koroutine mit Fehlerbehandlung über fold oder mapLeft aufgerufen werden, ohne den Thread zu blockieren. Dies ist besonders nützlich in Android-Apps mit MVVM-Architektur, bei denen jedes Repository Either zurückgibt und das ViewModel das Ergebnis in UiState umwandelt.

Häufige Fehler bei der Arbeit mit Either

Entwickler, die zum ersten Mal mit Either arbeiten, machen oft ähnliche Fehler. Betrachten wir die häufigsten und wie man sie vermeidet.

  • Left ignorieren — der Aufruf von .getOrElse() mit einem Standardwert ohne Analyse der Fehlerursache macht die Verwendung von Either sinnlos. Behandeln Sie den Fehler explizit.
  • Globaler Fehlertyp — die Verwendung von String oder Exception als gemeinsamen Typ für alle Either in einem Projekt reduziert die Typsicherheit. Erstellen Sie domänenspezifische versiegelte Klassen.
  • Verschachtelte Either — ein Either innerhalb von Right (Either<E, Either<E, A>>) erschwert die Lesbarkeit. Verwenden Sie flatMap zur Glättung.
  • Mischen mit Ausnahmen — eine Funktion gibt Either zurück, wirft aber intern Ausnahmen. Dies widerspricht der Idee der expliziten Fehlerbehandlung.

Häufig gestellte Fragen

Worin unterscheidet sich Either von Optional?

Optional repräsentiert das Vorhandensein oder Fehlen eines Werts (Some/None), gibt aber keinen Grund für das Fehlen an. Either bietet zwei konkrete Typen — links für Fehler und rechts für Erfolg — und ermöglicht so die Übergabe des Fehlerkontexts.

Kann Either in Java verwendet werden?

In Java gibt es kein integriertes Either, aber die Bibliotheken Vavr und functionaljava bieten Implementierungen. In der Android-Entwicklung ist Either von Vavr eine beliebte Alternative für einen funktionalen Stil mit Lambdas.

Wann sollte man sealed class anstelle von Either verwenden?

Sealed class in Kotlin ist praktischer, wenn es mehr als zwei Varianten gibt oder diese unterschiedliche Strukturen haben. Für ein binäres Ergebnis (Fehler/Erfolg) ist Either kompakter und bietet gebrauchsfertige funktionale Kombinatoren.

Unterstützt Either Multithreading?

Either ist unveränderlich und standardmäßig threadsicher. In Kotlin mit Koroutinen lässt sich Either hervorragend kombinieren: flatMap funktioniert innerhalb eines Koroutinen-Scopes, und die Fehlerbehandlung erfordert keine Sperren.

Sollte man Either für alle Funktionen im Projekt verwenden?

Nein. Either eignet sich für Operationen mit erwarteten Fehlern (Netzwerk, Validierung, Geschäftslogik). Für einfache Getter und Berechnungen ohne Nebenwirkungen ist ein normaler Typ leichter lesbar und fügt keine unnötige Komplexität hinzu.

Zusammenfassung

  • Either ist ein funktionaler Typ zur Darstellung von zwei Varianten: Left (Fehler) und Right (Erfolg), der die Fehlerbehandlung auf Typebene explizit macht.
  • Left kann im Gegensatz zum standardmäßigen Result einen beliebigen Fehlertyp enthalten — von String bis zu einer domänenspezifischen versiegelten Klasse.
  • flatMap ermöglicht die Komposition von Either ohne verschachtelte Prüfungen: Der Fehler propagiert automatisch durch die gesamte Kette.
  • Arrow ist die primäre Either-Bibliothek für Kotlin mit integrierter Koroutinen-Unterstützung und Erweiterungen.
  • Swift verwendet das integrierte Result, aber Either kann für maximale Flexibilität mit einem enum mit zwei generischen Parametern implementiert werden.
  • Verwenden Sie Either für Netzwerkanfragen, Formularvalidierung und Repositories — Szenarien mit erwarteten Fehlern.
  • Vermeiden Sie globale Fehlertypen, das Ignorieren von Left und verschachtelte Either — dies verringert die Vorteile der Typsicherheit.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch