Eitherは、2つの可能なバリアントのいずれかの値を表す関数型です。Leftはエラー、Rightは成功を示します。例外とは異なり、Eitherは型レベルでエラーハンドリングを明示的にし、try-catchブロックを必要としません。Arrow, 2026によると、EitherはKotlinプロジェクトで副作用なしに失敗する可能性のある操作を構成するために広く使用されています。
重要なポイント
Eitherは関数型プログラミングから借用された代数的データ型で、2つの可能な型のうち正確に1つの値を表します。エラーハンドリングの文脈では、慣例としてLeft型(Left)が問題の説明を含み、Right型(Right)が成功結果を含みます。
Eitherの概念はHaskell言語と型カテゴリEither a bに由来し、aは左の値の型、bは右の値の型です。モバイル開発では、EitherはKotlin用のArrowライブラリとSwiftの関数型アプローチによって広まりました。
例外に対するEitherの主な利点は隠れた実行パスがないことです。Eitherを返す関数は、そのシグネチャで失敗する可能性があることを明示的に宣言します。コンパイラは両方のバリアントが処理されていることを確認します。
例外をスローするのとは異なり、Eitherはデータフローの透過性を維持します。Eitherを返す関数の呼び出しは、呼び出し側でtry-catchを必要としません — pattern-matchingまたはfoldで十分です。これは、各データソースがEitherを返し、mapとflatMapを使用して変換チェーンが構築されるリアクティブアプローチのアーキテクチャで特に重要です。
EitherはLeftとRightの2つのサブタイプで構成されます。Eitherインスタンスは常にそのうちの1つだけです。Kotlinでの典型的なシグネチャはEither<E, A>で、Eはエラー型、Aは成功値の型です。
Leftは失敗のケースを表します。例外とは異なり、Leftは実行フローを中断しません — 処理が必要な値を返すだけです。エラー型は何でもかまいません:String、Int、カスタムのsealed class、またはドメインモデルです。
Rightは操作の正しい結果を含みます。名前が示すように、慣例によりRightは成功を意味します。mapやflatMapなどの変換はRightに適用され、各ステップをチェックすることなく計算チェーンを可能にします。
flatMapはEither合成の主要なメカニズムです。現在の値がRightの場合、flatMapは渡された関数を適用して新しいEitherを返します。Leftの場合、flatMapは変換をスキップしてエラーを伝播します。この動作はショートサーキット評価と呼ばれます。
flatMapに加えて、EitherはmapLeft(エラー変換用)、fold(両方のバリアントを1箇所で処理するため)、getOrElse(デフォルト値で値を抽出するため)をサポートします。これらの関数は、単純な抽出からKotlinコルーチンやSwift Combineでの非同期呼び出しを含む複雑な合成まで、すべてのシナリオをカバーします。
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) }
Kotlinエコシステムでは、EitherはArrowライブラリで実装されています。Kotlin標準ライブラリはResultを提供しますが、Eitherはより柔軟です:任意のエラー型、flatMapによる合成、関数型パターンのサポートを備えています。
ArrowはKotlin用の関数型ライブラリで、Either、Option、Validatedなどの型を追加します。Arrow.Eitherは2つのサブクラスを持つsealed classです:ArrowCore.LeftとArrowCore.Right。ライブラリは便利な拡張も提供します:.getOrElse()、.fold()、.mapLeft()。
実際のシナリオを考えてみましょう — ネットワークなし、サーバーエラー、不正な応答などのエラーが発生する可能性のあるAndroidアプリでのネットワークリクエストです。Eitherを使用すると、すべてのバリアントを1つの戻り値の型にまとめることができます。
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ではバージョン5.0以降、組み込みのResult型が利用可能で、概念的にはEitherに似ていますが制限があります:エラーはErrorプロトコルに準拠する必要があり、成功値は1つの型である必要があります。SwiftでのEitherは、2つのジェネリックパラメータを持つenumを使用して実装されます。
Result<Success, Failure>はSwiftの組み込み型で、Failure: Errorです。Eitherはエラー型に制約を課さないため、String、カスタム構造体、ネストされた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は、例外なしで明示的かつ型安全なエラーハンドリングが必要なシナリオに最適です。KotlinとSwiftでのモバイル開発における主な使用例を考えてみましょう。
副作用のない単純な操作にはEitherを使用しないでください — 通常の戻り値の方が信頼性が高く読みやすいです。また、失敗が例外的な状況であり予期されるシナリオでない場合、Eitherは過剰です。
EitherはKotlinのコルーチンでの作業にも効果的です。Eitherを返す関数は、スレッドをブロックせずにfoldまたはmapLeftによるエラーハンドリングとともにコルーチン内で呼び出すことができます。これは、各リポジトリがEitherを返し、ViewModelが結果をUiStateに変換するMVVMアーキテクチャのAndroidアプリで特に便利です。
Eitherに初めて触れる開発者は、よく似たような間違いを犯します。最も一般的なものとその回避方法を見てみましょう。
よくある質問
Optionalは値の有無(Some/None)を表しますが、欠如の理由は伝えません。Eitherはエラー用の左と成功用の右の2つの具体的な型を提供し、障害のコンテキストを伝達できます。
Javaには組み込みのEitherはありませんが、Vavrやfunctionaljavaライブラリが実装を提供しています。Android開発では、VavrのEitherがラムダを使用した関数型スタイルの一般的な代替手段です。
KotlinのSealed classは、3つ以上のバリアントがある場合や構造が異なる場合に便利です。2値の結果(エラー/成功)には、Eitherの方がコンパクトで、すぐに使える関数型コンビネータを提供します。
Eitherは不変であり、デフォルトでスレッドセーフです。Kotlinのコルーチンでは、Eitherは完全に組み合わせ可能です:flatMapはコルーチンスコープ内で機能し、エラーハンドリングにロックは必要ありません。
いいえ。Eitherは予期される失敗(ネットワーク、検証、ビジネスロジック)のある操作に適しています。副作用のない単純なゲッターや計算には、通常の型の方が読みやすく、不必要な複雑さを追加しません。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。