0Pricing
Kotlin Academy · レッスン

Either<L, R>:例外を使わない型付きエラー処理

例外をスローせずに成功と失敗を表すには、Eitherを使用します。

「Either<L, R>:例外を使わない型付きエラー処理」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。

ビジネスロジックに例外を使う問題点

例外は、予期しない失敗(nullポインター、I/Oエラーなど)のために設計されています。予期されるビジネス上の失敗(バリデーション失敗、「見つからない」など)を通知するために例外を使うと、制御フローが見えにくくなり、呼び出し箇所ごとにtry/catchが必要になり、関数シグネチャからエラーが分からなくなります。

Either<L, R>とは

Eitherは2つのケースを持つ直和型です。慣例として、Left(value: L)にはエラーを、Right(value: R)には成功した値を格納します。Eitherを返す関数では、失敗する可能性がシグネチャに明示されます。

ArrowのEither

プロジェクトにArrowを追加すると、Eitherと、その豊富な演算子エコシステムを利用できます。

// build.gradle.kts
implementation("io.arrow-kt:arrow-core:1.2.4")

// Usage
import arrow.core.Either
import arrow.core.left
import arrow.core.right

関数からEitherを返す

成功時はvalue.right()を、失敗時はerror.left()を返します。呼び出し側では両方の分岐を処理する必要があります。

sealed class UserError { object NotFound : UserError(); data class InvalidEmail(val msg: String) : UserError() }

fun findUser(id: Long): Either<UserError, User> =
    if (id <= 0) UserError.NotFound.left()
    else User(id, "Alice").right()

foldでEitherを処理する

fold(ifLeft, ifRight)を使用すると、1つの式で両方のケースを処理できます。

val result = findUser(1L)
val message = result.fold(
    ifLeft  = { error -> "Error: $error" },
    ifRight = { user  -> "Found: ${user.name}" }
)
println(message)

mapでRightの値を変換する

map { }はLeftには触れずにRightの値を変換します。これによりEitherはファンクターとして機能し、変換を安全に連結できます。

val nameResult: Either<UserError, String> = findUser(1L).map { it.name }

flatMapで処理を連結する

flatMap { }は、それ自体がEitherを返す計算を連結します。いずれかのステップがLeftを返すと、連結処理はそこで短絡し、後続のステップを実行せずにエラーが伝播します。

fun validateEmail(email: String): Either<UserError, String> =
    if (email.contains("@")) email.right()
    else UserError.InvalidEmail("bad format").left()

fun createUser(email: String): Either<UserError, User> =
    validateEmail(email).flatMap { validEmail ->
        User(1L, validEmail).right()
    }

Either.catchで例外をラップする

Either.catch { }はブロックを実行し、発生した例外をLeftとしてラップします。例外をスローするレガシーコードと、Eitherベースのドメインとの境界で使用します。

val result: Either<Throwable, User> = Either.catch {
    userRepository.findOrThrow(id)
}

getOrElseとorElseで復旧する

getOrElse { default }はRightの値を取り出し、Rightでなければデフォルト値を返します。orElse { alternativeEither }はLeftを別の計算結果に置き換えます。

val user: User = findUser(0L).getOrElse { User(-1L, "Guest") }
val user2: Either<UserError, User> = findUser(0L).orElse { User(99L, "Default").right() }

whenによるパターンマッチング

sealedなEither風クラスに対してwhenを使用するか、is Either.Left / Either.Rightを使ってEither自体に対して使用すると、すべてのケースを網羅的に処理できます。

when (val r = findUser(1L)) {
    is Either.Left  -> println("Error: ${r.value}")
    is Either.Right -> println("User: ${r.value.name}")
}

サービスレイヤーでEitherを使う

リポジトリ関数とサービス関数からEitherを返します。KtorのルートレベルでHTTPレスポンスに変換することで、ビジネスロジックをフレームワークの関心事から分離できます。

get("/users/{id}") {
    val id = call.parameters["id"]?.toLongOrNull() ?: return@get call.respond(HttpStatusCode.BadRequest)
    userService.findById(id).fold(
        ifLeft  = { call.respond(HttpStatusCode.NotFound) },
        ifRight = { call.respond(it) }
    )
}

理解度チェック

Either.Leftの値に対してflatMap { }を実行すると、どうなりますか。

振り返り:Either<L, R>

主なポイント:

  • Eitherによって、失敗時の処理が関数シグネチャに明示されます
  • Right = 成功。Left = 失敗(慣例)
  • map { } — 成功した値を変換します。flatMap { } — 失敗する可能性のある計算を連結します
  • fold(ifLeft, ifRight) — 1つの式で両方のケースを処理します
  • Either.catch { } — 例外をスローするコードを境界でラップします

よくある質問

「Either<L, R>:例外を使わない型付きエラー処理」レッスンは無料ですか?

はい。「Either<L, R>:例外を使わない型付きエラー処理」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。

「Either<L, R>:例外を使わない型付きエラー処理」で何を学びますか?

例外をスローせずに成功と失敗を表すには、Eitherを使用します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Kotlin Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「Either<L, R>:例外を使わない型付きエラー処理」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このKotlin Academyレッスンでコードを書いて実行できますか?

はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Either :例外を使わない型付きエラー処理
  2. Arrow Raise DSL:型付きエラーの合成
  3. OptionとNullable:それぞれを使う場面
  4. Arrowのコア型による関数型ドメインモデリング
← Kotlin Academyに戻る