Either is a functional type that represents a value of one of two possible variants: Left for errors and Right for success. Unlike exceptions, Either makes error handling explicit at the type level and does not require try-catch blocks. According to Arrow, 2026, Either is widely used in Kotlin projects for composing operations that may fail, without side effects.
Key Takeaways
Either is an algebraic data type, borrowed from functional programming, that represents exactly one of two possible types. In the context of error handling, the convention is: the Left type (Left) contains a problem description, while the Right type (Right) holds a successful result.
The concept of Either originates from the Haskell language and the type category Either a b, where a is the type of the left value and b is the type of the right. In mobile development, Either gained popularity thanks to the Arrow library for Kotlin and functional approaches in Swift.
The key advantage of Either over exceptions is no hidden execution paths. A function returning Either explicitly declares in its signature that it may fail. The compiler ensures both variants are handled.
Unlike throwing exceptions, Either preserves data flow transparency. Calling a function that returns Either does not require try-catch on the caller side — pattern matching or fold is sufficient. This is especially important in architectures with a reactive approach, where each data source returns Either and transformation chains are built using map and flatMap.
Either consists of two subtypes: Left and Right. An Either instance can only be one of them at any given time. The typical signature in Kotlin looks like Either<E, A>, where E is the error type and A is the success value type.
Left represents the failure case. Unlike exceptions, Left does not interrupt the execution flow — it simply returns a value that needs to be handled. The error type can be anything: String, Int, a custom sealed class, or a domain model.
Right holds the correct operation result. The name reflects correctness — by convention, Right means success. Transformations like map and flatMap are applied to Right, enabling computation chains without checking each step.
flatMap is the primary mechanism for composing Either. If the current value is Right, flatMap applies the passed function and returns a new Either. If it is Left, flatMap skips the transformation and propagates the error. This behavior is called short-circuit evaluation.
Besides flatMap, Either supports mapLeft for error transformation, fold for handling both variants in one place, and getOrElse for extracting a value with a default. These functions cover all scenarios: from simple extraction to complex composition with asynchronous calls in Kotlin coroutines or Swift Combine.
fun parseInt(input: String): Either<String, Int> =
input.toIntOrNull()?.let { Right(it) }
?: Left("Failed to convert: $input")
fun divide(a: Int, b: Int): Either<String, Int> =
if (b == 0) Left("Division by zero")
else Right(a / b)
val result = parseInt("10")
.flatMap { divide(it, 2) }
In the Kotlin ecosystem, Either is implemented in the Arrow library. The Kotlin standard library offers Result, but Either provides more flexibility: arbitrary error types, composition via flatMap, and support for functional patterns.
Arrow is a functional library for Kotlin that adds Either, Option, Validated, and other types. Arrow.Either is a sealed class with two subclasses: ArrowCore.Left and ArrowCore.Right. The library also provides convenient extensions: .getOrElse(), .fold(), .mapLeft().
Consider a real-world scenario — a network request in an Android app with possible errors: no network, server error, invalid response. Either allows combining all variants into a single return type.
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 ?: ""))
}
}
In Swift, starting from version 5.0, the built-in Result type is available, which is conceptually similar to Either but has limitations: the error must conform to the Error protocol, and the success value must be a single type. Either in Swift is implemented using an enum with two generic parameters.
Result<Success, Failure> is Swift's built-in type, where Failure: Error. Either does not impose constraints on the error type, allowing it to store String, custom structures, or even multiple error types through nested enums.
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 }
Either is optimal for scenarios requiring explicit and type-safe error handling without exceptions. Consider the main use cases in mobile development with Kotlin and Swift.
Avoid using Either for simple operations without side effects — a regular return value is more reliable and easier to read. Either is also excessive when failure is an exceptional situation rather than an expected scenario.
Either is also efficient when working with coroutines in Kotlin. A function returning Either can be called inside a coroutine with error handling via fold or mapLeft without blocking the thread. This is especially useful in Android apps with MVVM architecture, where each repository returns Either and the ViewModel transforms the result into UiState.
Developers new to Either often make similar mistakes. Let us examine the most common ones and how to avoid them.
Frequently Asked Questions
Optional represents the presence or absence of a value (Some/None) but does not convey the reason for absence. Either provides two specific types — left for error and right for success — allowing error context to be passed along.
Java does not have a built-in Either, but libraries like Vavr and functionaljava provide implementations. In Android development, Either from Vavr is a popular alternative for a functional style with lambdas.
Sealed class in Kotlin is more convenient when there are more than two variants or when they have different structures. For a binary outcome (error/success), Either is more compact and provides ready-to-use functional combinators.
Either is immutable and thread-safe by default. In Kotlin with coroutines, Either combines perfectly: flatMap works inside a coroutine scope, and error handling does not require locks.
No. Either is suitable for operations with expected failures (network, validation, business logic). For simple getters and computations without side effects, a regular type is easier to read and does not add unnecessary complexity.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also