Either: суштина, примена и принцип рада

Аутор: IT Sectr Објављено: 2026-05-26 Време читања: 8 мин

Either — функционални тип који представља вредност једне од две могуће варијанте: лева (Left) за грешку и десна (Right) за успех. За разлику од изузетака, Either чини обраду грешака експлицитном на нивоу типова и не захтева блокове try-catch. Према подацима Arrow, 2026, Either се широко примењује у Kotlin пројектима за композицију операција које могу да заврше неуспехом, без споредних ефеката.

Главно

  • Either — алгебарски тип података за представљање две међусобно искључиве варијанте: Left (грешка) и Right (успех).
  • Left традиционално садржи информацију о грешци, Right — исправну вредност.
  • Експлицитна типизација — Either приморава обраду обе варијанте у фази компилације, искључујући неочекиване отказе.
  • Композиција — Either подржава map, flatMap и fold за ланце трансформација без угњеждених провера.
  • Разлика од Result — Either може да складишти произвољан тип грешке, не само Error или Throwable.

Шта је Either?

Either — је алгебарски тип података позајмљен из функционалног програмирања, који представља вредност тачно једног од два могућа типа. У контексту обраде грешака усвојена је конвенција: леви тип (Left) садржи опис проблема, а десни (Right) — успешан резултат.

Концепт Either потиче из језика Haskell и категорије типова Either a b, где a представља тип леве вредности, b — десне. У мобилном развоју, Either је стекао популарност захваљујући библиотеци Arrow за Kotlin и функционалним приступима у Swift.

Кључна предност Either над изузецима — одсуство скривених путања извршења. Функција која враћа Either експлицитно изјављује у свом потпису да може да се заврши грешком. Компилатор контролише да ли су обе варијанте обрађене.

За разлику од бацања изузетака, Either чува транспарентност тока података. Позив функције која враћа Either не захтева try-catch на страни позивајућег кода — довољан је pattern-matching или fold. Ово је посебно важно у архитектурама са реактивним приступом, где сваки извор података враћа Either, а ланац трансформација се гради кроз map и flatMap.

Како ради Either: структура Left и Right

Either се састоји од два подтипа: Left и Right. Инстанца Either може бити само једна од њих у сваком тренутку. Типичан потпис у Kotlin изгледа као Either<E, A>, где E представља тип грешке, A — тип успешне вредности.

Тип Left: контејнер грешке

Left представља случај отказа. За разлику од изузетака, Left не прекида ток извршења — једноставно враћа вредност коју треба обрадити. Тип грешке може бити било који: String, Int, прилагођени sealed class или доменски модел.

Тип Right: контејнер успеха

Right садржи исправан резултат операције. Назив одражава „исправност" — по конвенцији Right значи успех. Управо на Right се примењују трансформације map и flatMap, што омогућава градњу ланаца прорачуна без провере сваког корака.

Композиција Either кроз flatMap

flatMap — главни механизам композиције Either. Ако је тренутна вредност Right, flatMap примењује прослеђену функцију и враћа нови Either. Ако је Left — flatMap прескаче трансформацију и прослеђује грешку даље. Ово понашање се назива short-circuit evaluation.

Поред flatMap, Either подржава mapLeft за трансформацију грешке, fold за обраду обе варијанте на једном месту и getOrElse за издвајање вредности са подразумеваном. Ове функције покривају све сценарије: од једноставног издвајања до сложене композиције са асинхроним позивима у корутинама Kotlin или Combine у Swift.

kotlin
fun parseInt(input: String): Either<String, Int> =
    input.toIntOrNull()?.let { Right(it) }
    ?: Left("Није могуће конвертовати: $input")

fun divide(a: Int, b: Int): Either<String, Int> =
    if (b == 0) Left("Дељење нулом")
    else Right(a / b)

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

Either у Kotlin: практична примена

У екосистему Kotlin Either је имплементиран у библиотеци Arrow. Стандардна библиотека Kotlin нуди Result, али Either даје више флексибилности: произвољан тип грешке, композицију кроз flatMap и подршку за функционалне обрасце.

Библиотека Arrow и Either

Arrow — функционална библиотека за Kotlin која додаје Either, Option, Validated и друге типове. Arrow.Either — sealed class са два наследника: ArrowCore.Left и ArrowCore.Right. Библиотека такође пружа проширења за згодан рад: .getOrElse(), .fold(), .mapLeft().

Пример: Either са мрежним захтевом

Размотримо реалан сценарио — мрежни захтев у Android апликацији са могућим грешкама: недостатак мреже, грешка сервера, неисправан одговор. Either омогућава обједињавање свих варијанти у једном повратном типу.

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 у Swift: разлика од стандардног Result

У Swift од верзије 5.0 појавио се уграђени тип Result, који је концептуално сличан Either, али има ограничења: грешка мора да одговара протоколу Error, а успешна вредност — једном типу. Either у Swift се имплементира кроз enum са два генеричка параметра.

Стандардни Result у односу на Either

Result<Success, Failure> — уграђени тип Swift, где Failure: Error. Either не намеће ограничења на тип грешке, што омогућава складиштење String, прилагођених структура или чак више типова грешака кроз угњеждене enum.

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 }

Када користити Either у мобилним апликацијама

Either је оптималан за сценарије који захтевају експлицитну и типолошки безбедну обраду грешака без изузетака. Размотримо главне случајеве примене у мобилном развоју на Kotlin и Swift.

  • Мрежни захтеви — сваки захтев може да врати грешку везе, сервера или парсирања. Either сакупља све варијанте у један тип.
  • Валидација форми — Either са прилагођеним типом грешке згодно представља резултат провере поља уноса: неисправан email или лозинка.
  • Репозиторијум података — Either омогућава обједињавање резултата из различитих извора (кеш, база података, мрежа) са јединственим типом грешке.
  • Интерпретатор команди — ако апликација анализира кориснички унос или команде, Either пружа типолошки безбедан начин за пријаву грешке.

Немојте користити Either за једноставне операције без споредних ефеката — обична повратна вредност је поузданија и читљивија. Either је такође сувишан када је отказ изузетна ситуација, а не очекивани сценарио.

Either је такође ефикасан при раду са корутинама у Kotlin. Функција која враћа Either може бити позвана унутар корутине са обрадом грешке кроз fold или mapLeft без блокирања нити. Ово је посебно корисно у Android апликацијама са MVVM архитектуром, где сваки репозиторијум враћа Either, а ViewModel трансформише резултат у UiState.

Типичне грешке при раду са Either

Програмери који се први пут сусрећу са Either често праве сличне грешке. Размотримо најчешће и начине да их избегнемо.

  • Игнорисање Left — позив .getOrElse() са подразумеваном вредношћу без анализе узрока грешке лишава смисла употребу Either. Обрађујте грешку експлицитно.
  • Глобални тип грешке — коришћење String или Exception као заједничког типа за све Either у пројекту смањује типолошку безбедност. Креирајте доменске sealed class.
  • Угњеждени Either — поновљени Either унутар Right (Either<E, Either<E, A>>) отежава читање. Користите flatMap за изравнавање.
  • Мешање са изузецима — функција враћа Either, али унутра баца изузетак. Ово је у супротности са идејом експлицитне обраде грешака.

Често постављана питања

Чим се Either разликује од Optional?

Optional представља присуство или одсуство вредности (Some/None), али не саопштава узрок одсуства. Either даје два конкретна типа — леви за грешку и десни за успех, што омогућава преношење контекста отказа.

Може ли се Either користити у Java?

У Java не постоји уграђени Either, али библиотеке Vavr и functionaljava пружају имплементацију. У Android развоју, Either из Vavr је популарна алтернатива за функционални стил са ламбда изразима.

Када је боље користити sealed class уместо Either?

Sealed class у Kotlin је згоднији када варијанти има више од две или имају различиту структуру. За бинарни исход (грешка/успех) Either је компактнији и пружа готове функционалне комбинаторе.

Да ли Either подржава вишенитност?

Either је имутабилан и безбедан за нити подразумевано. У Kotlin са корутинама Either се одлично комбинује: flatMap ради унутар coroutine scope, а обрада грешака не захтева блокаде.

Да ли вреди користити Either за све функције у пројекту?

Не. Either је прикладан за операције са очекиваним отказима (мрежа, валидација, пословна логика). За једноставне гетере и прорачуне без споредних ефеката обичан тип је читљивији и не додаје непотребну сложеност.

Закључци

  • Either — функционални тип за представљање две варијанте: Left (грешка) и Right (успех), чинећи обраду отказа експлицитном на нивоу типова.
  • Left може да садржи произвољан тип грешке — од String до доменског sealed class, за разлику од стандардног Result.
  • flatMap обезбеђује композицију Either без угњеждених провера: грешка се аутоматски пропагира кроз цео ланац.
  • Arrow — главна библиотека Either за Kotlin са уграђеном подршком за корутине и проширења.
  • Swift користи уграђени Result, али Either се имплементира кроз enum са два генеричка параметра за пуну флексибилност.
  • Примењујте Either за мрежне захтеве, валидацију форми и репозиторијуме — сценарије са очекиваним грешкама.
  • Избегавајте глобални тип грешке, игнорисање Left и угњеждене Either — то смањује предности типолошке безбедности.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође