Either: esensya, aplikasyon, at prinsipyo ng paggana

May-akda: IT Sectr Nai-publish: 2026-05-26 Oras ng pagbabasa: 8 min

Either — isang functional na uri na kumakatawan sa halaga ng isa sa dalawang posibleng variant: kaliwa (Left) para sa error at kanan (Right) para sa tagumpay. Hindi tulad ng mga exception, ginagawang tahasan ng Either ang paghawak ng error sa antas ng uri at hindi nangangailangan ng mga bloke ng try-catch. Ayon sa datos ng Arrow, 2026, ang Either ay malawakang ginagamit sa mga proyekto ng Kotlin para sa komposisyon ng mga operasyon na maaaring mabigo, nang walang mga side effect.

Mga Pangunahing Punto

  • Either — isang algebraikong uri ng datos para sa kumatawan sa dalawang magkasalungat na variant: Left (error) at Right (tagumpay).
  • Left ay tradisyonal na naglalaman ng impormasyon tungkol sa error, Right — ang tamang halaga.
  • Tahasang tipipikasyon — pinipilit ng Either na ang parehong variant ay hawakan sa yugto ng compilation, inaalis ang hindi inaasahang pagkabigo.
  • Komposisyon — Sinusuportahan ng Either ang map, flatMap, at fold para sa mga chain ng pagbabago nang walang nested na pagsusuri.
  • Pagkakaiba sa Result — Maaaring mag-imbak ang Either ng anumang uri ng error, hindi lang Error o Throwable.

Ano ang Either?

Either — ay isang algebraikong uri ng datos na hiram mula sa functional programming, na kumakatawan sa halaga ng eksaktong isa sa dalawang posibleng uri. Sa konteksto ng paghawak ng error, ang kombensyon ay: ang kaliwang uri (Left) ay naglalaman ng paglalarawan ng problema, at ang kanan (Right) — ang matagumpay na resulta.

Ang konsepto ng Either ay nagmula sa wikang Haskell at kategorya ng mga uri Either a b, kung saan a ay ang uri ng kaliwang halaga, b — ng kanan. Sa pag-develop ng mobile, naging popular ang Either salamat sa library na Arrow para sa Kotlin at mga functional na diskarte sa Swift.

Ang pangunahing bentahe ng Either kaysa sa mga exception — kawalan ng nakatagong mga landas ng pagpapatupad. Ang isang function na nagbabalik ng Either ay tahasang nagdedeklara sa kanyang lagda na maaari itong magtapos sa error. Kinokontrol ng compiler kung ang parehong variant ay nahawakan na.

Hindi tulad ng paghagis ng exception, pinapanatili ng Either ang transparency ng daloy ng datos. Ang pagtawag sa isang function na nagbabalik ng Either ay hindi nangangailangan ng try-catch sa panig ng tumatawag na code — sapat na ang pattern-matching o fold. Ito ay lalong mahalaga sa mga arkitektura na may reaktibong diskarte, kung saan ang bawat pinagmulan ng datos ay nagbabalik ng Either, at ang chain ng pagbabago ay binuo sa pamamagitan ng map at flatMap.

Paano gumagana ang Either: istraktura ng Left at Right

Ang Either ay binubuo ng dalawang subtype: Left at Right. Ang isang instance ng Either ay maaari lamang maging isa sa mga ito sa bawat sandali. Ang tipikal na lagda sa Kotlin ay mukhang Either<E, A>, kung saan E ay ang uri ng error, A — ang uri ng matagumpay na halaga.

Uri ng Left: lalagyan ng error

Left ay kumakatawan sa kaso ng pagkabigo. Hindi tulad ng mga exception, hindi pinipigilan ng Left ang daloy ng pagpapatupad — ito ay nagbabalik lamang ng isang halaga na kailangang hawakan. Ang uri ng error ay maaaring kahit ano: String, Int, custom na sealed class, o modelo ng domain.

Uri ng Right: lalagyan ng tagumpay

Right ay naglalaman ng tamang resulta ng operasyon. Ang pangalan ay sumasalamin sa “katumpakan” — ayon sa kombensyon, ang Right ay nangangahulugang tagumpay. Sa Right inilalapat ang mga pagbabagong map at flatMap, na nagpapahintulot sa pagbuo ng mga chain ng pag-compute nang hindi sinusuri ang bawat hakbang.

Komposisyon ng Either sa pamamagitan ng flatMap

flatMap — ang pangunahing mekanismo ng komposisyon ng Either. Kung ang kasalukuyang halaga ay Right, inilalapat ng flatMap ang ibinigay na function at nagbabalik ng bagong Either. Kung Left — nilalaktawan ng flatMap ang pagbabago at ipinapasa ang error. Ang pag-uugaling ito ay tinatawag na short-circuit evaluation.

Bukod sa flatMap, sinusuportahan ng Either ang mapLeft para sa pagbabago ng error, fold para sa paghawak ng parehong variant sa isang lugar, at getOrElse para sa pag-extract ng halaga na may default. Ang mga function na ito ay sumasaklaw sa lahat ng senaryo: mula sa simpleng pag-extract hanggang sa kumplikadong komposisyon na may asynchronous na tawag sa Kotlin coroutine o Combine sa Swift.

kotlin
fun parseInt(input: String): Either<String, Int> =
    input.toIntOrNull()?.let { Right(it) }
    ?: Left("Hindi ma-convert: $input")

fun divide(a: Int, b: Int): Either<String, Int> =
    if (b == 0) Left("Pag-divide sa zero")
    else Right(a / b)

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

Either sa Kotlin: praktikal na aplikasyon

Sa ecosystem ng Kotlin, ang Either ay ipinatupad sa library ng Arrow. Ang standard library ng Kotlin ay nag-aalok ng Result, ngunit ang Either ay nagbibigay ng higit na kakayahang umangkop: anumang uri ng error, komposisyon sa pamamagitan ng flatMap, at suporta para sa mga functional pattern.

Arrow library at Either

Arrow — isang functional na library para sa Kotlin na nagdaragdag ng Either, Option, Validated, at iba pang uri. Arrow.Either — sealed class na may dalawang tagapagmana: ArrowCore.Left at ArrowCore.Right. Nagbibigay din ang library ng mga extension para sa maginhawang trabaho: .getOrElse(), .fold(), .mapLeft().

Halimbawa: Either na may network request

Isaalang-alang natin ang isang totoong senaryo — isang network request sa isang Android app na may posibleng mga error: walang network, error sa server, hindi wastong tugon. Pinapayagan ng Either na pagsamahin ang lahat ng variant sa isang uri ng pagbabalik.

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 sa Swift: pagkakaiba mula sa standard na Result

Sa Swift mula sa bersyon 5.0, lumitaw ang built-in na uri na Result, na konseptuwal na katulad ng Either, ngunit may mga limitasyon: ang error ay dapat sumunod sa protocol na Error, at ang matagumpay na halaga — sa isang uri. Ang Either sa Swift ay ipinatupad sa pamamagitan ng enum na may dalawang generic na parameter.

Standard na Result kumpara sa Either

Result<Success, Failure> — ang built-in na uri ng Swift, kung saan Failure: Error. Ang Either ay hindi naglalagay ng mga paghihigpit sa uri ng error, na nagpapahintulot na mag-imbak ng String, mga custom na istraktura, o kahit maraming uri ng error sa pamamagitan ng nested 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 }

Kailan gagamitin ang Either sa mga mobile app

Either ay pinakamainam para sa mga senaryo na nangangailangan ng tahasan at ligtas na paghawak ng error nang walang exception. Tingnan natin ang mga pangunahing kaso ng paggamit sa pag-develop ng mobile sa Kotlin at Swift.

  • Mga network request — bawat request ay maaaring magbalik ng error sa koneksyon, server, o parsing. Kinokolekta ng Either ang lahat ng variant sa isang uri.
  • Pag-validate ng form — Either na may custom na uri ng error ay maginhawang kumakatawan sa resulta ng pagsusuri ng mga input field: hindi wastong email o password.
  • Repository ng datos — Pinapayagan ng Either na pagsamahin ang resulta mula sa iba't ibang source (cache, database, network) na may pare-parehong uri ng error.
  • Interpreter ng command — kung ang app ay nag-parse ng input ng user o mga command, nagbibigay ang Either ng ligtas na paraan upang mag-ulat ng error.

Huwag gamitin ang Either para sa mga simpleng operasyon nang walang side effect — ang ordinaryong halaga ng pagbabalik ay mas maaasahan at mas madaling basahin. Ang Either ay labis din kapag ang pagkabigo ay isang pambihirang sitwasyon, hindi isang inaasahang senaryo.

Either ay epektibo rin kapag nagtatrabaho sa mga coroutine sa Kotlin. Ang isang function na nagbabalik ng Either ay maaaring tawagin sa loob ng isang coroutine na may paghawak ng error sa pamamagitan ng fold o mapLeft nang hindi hinaharangan ang thread. Ito ay lalong kapaki-pakinabang sa mga Android app na may MVVM architecture, kung saan ang bawat repository ay nagbabalik ng Either, at ang ViewModel ay nagbabago ng resulta sa UiState.

Mga karaniwang pagkakamali sa pagtatrabaho sa Either

Ang mga developer na unang nakakakilala sa Either ay madalas na gumagawa ng mga katulad na pagkakamali. Tingnan natin ang mga pinaka-karaniwan at mga paraan upang maiwasan ang mga ito.

  • Pagbalewala sa Left — ang pagtawag ng .getOrElse() na may default na halaga nang hindi sinusuri ang sanhi ng error ay nag-aalis ng kahulugan ng paggamit ng Either. Hawakan ang error nang tahasan.
  • Pandaigdigang uri ng error — ang paggamit ng String o Exception bilang karaniwang uri para sa lahat ng Either sa proyekto ay nagbabawas ng kaligtasan ng uri. Gumawa ng domain sealed classes.
  • Nested na Either — paulit-ulit na Either sa loob ng Right (Either<E, Either<E, A>>) ay nagpapahirap sa pagbabasa. Gumamit ng flatMap para sa pagpapantay.
  • Paghahalo sa mga exception — ang function ay nagbabalik ng Either, ngunit sa loob ay naghahagis ng exception. Ito ay sumasalungat sa ideya ng tahasang paghawak ng error.

Mga Madalas Itanong

Ano ang pagkakaiba ng Either sa Optional?

Optional ay kumakatawan sa pagkakaroon o kawalan ng halaga (Some/None), ngunit hindi nagbibigay ng dahilan ng kawalan. Ang Either ay nagbibigay ng dalawang konkretong uri — kaliwa para sa error at kanan para sa tagumpay, na nagpapahintulot na ipasa ang konteksto ng pagkabigo.

Maaari bang gamitin ang Either sa Java?

Sa Java walang built-in na Either, ngunit ang mga library na Vavr at functionaljava ay nagbibigay ng implementasyon. Sa pag-develop ng Android, ang Either mula sa Vavr ay isang popular na alternatibo para sa functional na estilo na may lambda.

Kailan mas mahusay na gumamit ng sealed class sa halip ng Either?

Sealed class sa Kotlin ay mas maginhawa kapag ang mga variant ay higit pa sa dalawa o may iba't ibang istraktura. Para sa binary na kinalabasan (error/tagumpay) ang Either ay mas compact at nagbibigay ng mga handa na functional combinator.

Sinusuportahan ba ng Either ang multi-threading?

Either ay immutable at thread-safe bilang default. Sa Kotlin na may coroutine, ang Either ay mahusay na pinagsasama: ang flatMap ay gumagana sa loob ng coroutine scope, at ang paghawak ng error ay hindi nangangailangan ng pag-lock.

Dapat bang gamitin ang Either para sa lahat ng function sa proyekto?

Hindi. Either ay angkop para sa mga operasyon na may inaasahang pagkabigo (network, validation, business logic). Para sa mga simpleng getter at pag-compute na walang side effect, ang ordinaryong uri ay mas madaling basahin at hindi nagdaragdag ng hindi kinakailangang kumplikasyon.

Buod

  • Either — functional na uri para sa kumatawan sa dalawang variant: Left (error) at Right (tagumpay), ginagawang tahasan ang paghawak ng pagkabigo sa antas ng uri.
  • Left ay maaaring maglaman ng anumang uri ng error — mula String hanggang domain sealed class, hindi tulad ng standard na Result.
  • flatMap ay nagsisiguro ng komposisyon ng Either nang walang nested na pagsusuri: ang error ay awtomatikong kumakalat sa buong chain.
  • Arrow — ang pangunahing library ng Either para sa Kotlin na may built-in na suporta para sa coroutine at extension.
  • Swift ay gumagamit ng built-in na Result, ngunit ang Either ay ipinatupad sa pamamagitan ng enum na may dalawang generic na parameter para sa buong kakayahang umangkop.
  • Ilapat ang Either para sa mga network request, pag-validate ng form, at repository — mga senaryo na may inaasahang error.
  • Iwasan ang pandaigdigang uri ng error, pagbalewala sa Left, at nested na Either — ito ay nagbabawas ng mga bentahe ng kaligtasan ng uri.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din