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 — 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.
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.
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.
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.
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.
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) }
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 — 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().
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.
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 ?: ""))
}
}
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.
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.
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 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.
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.
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.
Mga Madalas Itanong
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.
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.
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.
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.
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
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.
Basahin din