Either — iki mümkün variantdan birinin dəyərini təmsil edən funksional tip: xəta üçün sol (Left) və uğur üçün sağ (Right). İstisnalardan fərqli olaraq, Either xəta idarəetməsini tip səviyyəsində aşkar edir və try-catch blokları tələb etmir. Arrow, 2026 məlumatlarına görə, Either Kotlin layihələrində uğursuz ola bilən əməliyyatların kompozisiyası üçün geniş istifadə olunur.
Əsas məqamlar
Either — funksional proqramlaşdırmadan götürülmüş, iki mümkün tipdən birinin dəyərini təmsil edən cəbri məlumat tipidir. Xəta idarəetməsi kontekstində konvensiya qəbul edilmişdir: sol tip (Left) problemi təsvir edir, sağ (Right) isə uğurlu nəticəni.
Either konsepsiyası Haskell dilinə və Either a b tip kateqoriyasına əsaslanır, burada a sol dəyərin tipi, b isə sağın tipidir. Mobil inkişafda Either Kotlin üçün Arrow kitabxanası və Swift-də funksional yanaşmalar sayəsində populyarlıq qazanmışdır.
Either-in istisnalar üzərində əsas üstünlüyü gizli icra yollarının olmamasıdır. Either qaytaran funksiya öz imzasında aşkar şəkildə xəta ilə nəticələnə biləcəyini bəyan edir. Kompilyator hər iki variantın işlənib-işlənmədiyini yoxlayır.
İstisnaların atılmasından fərqli olaraq, Either məlumat axınının şəffaflığını qoruyur. Either qaytaran funksiyanın çağırışı try-catch tələb etmir — pattern-matching və ya fold kifayətdir. Bu, hər bir məlumat mənbəyinin Either qaytardığı və çevrilmə zəncirinin map və flatMap vasitəsilə qurulduğu reaktiv yanaşmalı arxitekturalarda xüsusilə vacibdir.
Either iki alt tipdən ibarətdir: Left və Right. Either nümunəsi hər an yalnız onlardan biri ola bilər. Kotlin-də tipik imza Either<E, A> kimi görünür, burada E xəta tipi, A isə uğurlu dəyərin tipidir.
Left nasazlıq halını təmsil edir. İstisnalardan fərqli olaraq, Left icra axınını kəsmir — sadəcə işlənməli olan dəyəri qaytarır. Xəta tipi istənilən ola bilər: String, Int, fərdi sealed class və ya domen modeli.
Right əməliyyatın düzgün nəticəsini ehtiva edir. Ad „düzgünlük"ü əks etdirir — konvensiyaya görə Right uğur deməkdir. Məhz Right-a map və flatMap çevrilmələri tətbiq edilir ki, bu da hər addımı yoxlamadan hesablama zəncirləri qurmağa imkan verir.
flatMap — Either kompozisiyasının əsas mexanizmidir. Cari dəyər Right-dırsa, flatMap ötürülən funksiyanı tətbiq edir və yeni Either qaytarır. Left-dirsə — flatMap çevrilməni buraxır və xətanı ötürür. Bu davranış short-circuit evaluation adlanır.
flatMap-dən əlavə, Either mapLeft (xətanın çevrilməsi), fold (hər iki variantın bir yerdə işlənməsi) və getOrElse (defolt dəyərlə çıxarılma) funksiyalarını dəstəkləyir. Bu funksiyalar bütün ssenariləri əhatə edir: sadə çıxarmadan Kotlin korutinlərində və ya Swift-də Combine ilə asinxron çağırışların mürəkkəb kompozisiyasına qədər.
fun parseInt(input: String): Either<String, Int> =
input.toIntOrNull()?.let { Right(it) }
?: Left("$input çevrilə bilmədi")
fun divide(a: Int, b: Int): Either<String, Int> =
if (b == 0) Left("Sıfıra bölmə")
else Right(a / b)
val result = parseInt("10")
.flatMap { divide(it, 2) }
Kotlin ekosistemində Either Arrow kitabxanasında tətbiq edilmişdir. Kotlin-in standart kitabxanası Result təklif edir, lakin Either daha çox elastiklik verir: ixtiyari xəta tipi, flatMap ilə kompozisiya və funksional nümunələr üçün dəstək.
Arrow — Kotlin üçün Either, Option, Validated və digər tipləri əlavə edən funksional kitabxanadır. Arrow.Either — iki varisi olan sealed class: ArrowCore.Left və ArrowCore.Right. Kitabxana həmçinin rahat iş üçün genişlənmələr təqdim edir: .getOrElse(), .fold(), .mapLeft().
Real ssenarini nəzərdən keçirək — Android tətbiqində mümkün xətalarla şəbəkə sorğusu: şəbəkə yoxdur, server xətası, yanlış cavab. Either bütün variantları bir qaytarılan tipdə birləşdirməyə imkan verir.
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 ?: ""))
}
}
Swift-də 5.0 versiyasından etibarən Result tipi mövcuddur ki, bu da konseptual olaraq Either-ə bənzəyir, lakin məhdudiyyətləri var: xəta Error protokoluna uyğun olmalıdır, uğurlu dəyər isə bir tipə. Swift-də Either iki generic parametrli enum vasitəsilə tətbiq edilir.
Result<Success, Failure> — Swift-in daxili tipi, burada Failure: Error. Either xəta tipinə məhdudiyyət qoymur ki, bu da String, fərdi strukturlar və ya iç-içə enumlar vasitəsilə bir neçə xəta tipini saxlamağa imkan verir.
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 istisnasız, aşkar və tip təhlükəsiz xəta idarəetməsi tələb edən ssenarilər üçün optimaldır. Kotlin və Swift-də mobil inkişafda əsas tətbiq hallarını nəzərdən keçirək.
Either-i yan təsirləri olmayan sadə əməliyyatlar üçün istifadə etməyin — adi qaytarılan dəyər daha etibarlı və oxunaqlıdır. Either həmçinin nasazlıq gözlənilən ssenari deyil, müstəsna hal olduqda da lazımsızdır.
Either Kotlin-də korutinlərlə işləyərkən də effektivdir. Either qaytaran funksiya korutin daxilində fold və ya mapLeft ilə xəta idarəetməsi ilə, thread-i bloklamadan çağrıla bilər. Bu, hər repozitoriyanın Either qaytardığı və ViewModel-in nəticəni UiState-ə çevirdiyi MVVM arxitekturalı Android tətbiqlərində xüsusilə faydalıdır.
Either ilə ilk dəfə tanış olan proqramçılar tez-tez oxşar səhvlərə yol verirlər. Ən geniş yayılmış səhvləri və onlardan qaçma yollarını nəzərdən keçirək.
Tez-tez verilən suallar
Optional dəyərin mövcudluğunu və ya yoxluğunu (Some/None) təmsil edir, lakin yoxluğun səbəbini bildirmir. Either iki konkret tip verir — xəta üçün sol və uğur üçün sağ, bu da nasazlıq kontekstini ötürməyə imkan verir.
Java-da daxili Either yoxdur, lakin Vavr və functionaljava kitabxanaları tətbiq təmin edir. Android inkişafında Vavr-dan Either lambda ilə funksional stil üçün məşhur alternativdir.
Sealed class Kotlin-də variantlar ikidən çox olduqda və ya fərqli strukturda olduqda daha rahatdır. İkili nəticə (xəta/uğur) üçün Either daha yığcamdır və hazır funksional kombinatorlar təqdim edir.
Either dəyişməzdir və defolt olaraq thread təhlükəsizdir. Kotlin-də korutinlərlə Either əla birləşir: flatMap coroutine scope daxilində işləyir, xəta idarəetməsi isə bloklamalar tələb etmir.
Xeyr. Either gözlənilən nasazlıqları olan əməliyyatlar üçün uyğundur (şəbəkə, validasiya, biznes məntiqi). Sadə getterlər və yan təsirsiz hesablamalar üçün adi tip daha oxunaqlıdır və lazımsız mürəkkəblik əlavə etmir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun