0Pricing
Scala for Backend Engineering & Functional Programming · レッスン

型の相互変換

Option、Either、Try です。

「型の相互変換」はCoddyKit上の無料Scala for Backend Engineering & Functional Programmingレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはScala for Backend Engineering & Functional Programming学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

3 つのエラーモデル

Scala には、値の不在と失敗を表す相補的な 3 つの型があります。

  • Option — 存在または不在(理由はありません)。
  • Either — 成功または型付きエラー。
  • Try — 成功またはスローされた例外。

これらの間で変換する方法を知っていれば、ある API を別の API に適応させられます。

Option から Either へ

toRightはOptionをEitherに変換し、Noneの場合はLeftのエラーを指定します。toLeftは逆方向にマッピングします。

@main def run(): Unit = {
  val some: Option[Int] = Some(5)
  val none: Option[Int] = None
  println(some.toRight("missing"))
  println(none.toRight("missing"))
}

EitherからOptionへ

toOptionはエラーを破棄します。Right(x)はSome(x)に、Left(_)はNoneになります。失敗の理由がもはや重要でない場合に使用します。

@main def run(): Unit = {
  val r: Either[String, Int] = Right(42)
  val l: Either[String, Int] = Left("err")
  println(r.toOption)
  println(l.toOption)
}

TryからOptionへ

Try.toOptionはSuccessをSomeに、FailureをNoneに変換し、例外を握りつぶします。

import scala.util.Try

@main def run(): Unit = {
  println(Try("7".toInt).toOption)
  println(Try("x".toInt).toOption)
}

TryからEitherへ

Try.toEitherはEither[Throwable, T]を生成します。SuccessはRightに、FailureはLeft(throwable)になります。これにより、例外を型付きのleftとして保持できます。

import scala.util.Try

@main def run(): Unit = {
  val ok = Try("7".toInt).toEither
  val no = Try("x".toInt).toEither
  println(ok)
  println(no.left.map(_.getMessage))
}

EitherからTryへ

単純なエラーを持つEitherからTryへの直接的な組み込み変換はありませんが、自分で作成できます。RightをSuccessでラップし、Leftを例外を保持するFailureでラップします。

import scala.util.{Try, Success, Failure}

object Main {
  def toTry(e: Either[String, Int]): Try[Int] = e match {
    case Right(v) => Success(v)
    case Left(m)  => Failure(new RuntimeException(m))
  }

  def main(args: Array[String]): Unit = {
    println(toTry(Right(1)))
    println(toTry(Left("bad")))
  }
}

OptionからTryへ

空の場合に使用する例外を選ぶことで、OptionをTryに変換できます。APIがTryを要求する場合に便利です。

import scala.util.{Try, Success, Failure}

object Main {
  def toTry[A](o: Option[A]): Try[A] = o match {
    case Some(v) => Success(v)
    case None    => Failure(new NoSuchElementException("empty"))
  }

  def main(args: Array[String]): Unit = {
    println(toTry(Some(9)))
    println(toTry(None))
  }
}

パイプラインの正規化

型を混在させると扱いにくくなります。一般的な方法は、早い段階ですべてを統一されたエラー型のEitherに変換し、その後は自由に合成することです。

import scala.util.Try

object Main {
  def parse(s: String): Either[String, Int] =
    Try(s.toInt).toEither.left.map(_ => s"invalid: $s")

  def lookup(n: Int): Either[String, String] =
    Map(1 -> "one", 2 -> "two").get(n).toRight(s"no entry for $n")

  def main(args: Array[String]): Unit = {
    val result = for {
      n <- parse("2")
      w <- lookup(n)
    } yield w
    println(result)
  }
}

型をまたいだgetOrElse

3つの型はいずれも、getOrElseで値を取り出すか、デフォルト値を指定できます。これは多くの場合、エラー処理の世界から抜ける最後のステップです。

import scala.util.Try

@main def run(): Unit = {
  val a = Some(1).getOrElse(0)
  val b = (Right(2): Either[String, Int]).getOrElse(0)
  val c = Try("x".toInt).getOrElse(0)
  println(s"$a $b $c")
}

適切な型の選択

指針:

  • 不在について説明が不要な場合はOptionを使用します。
  • ドメイン固有のエラー値が必要な場合はEitherを使用します。
  • 例外をスローするJavaやライブラリのコードとの境界ではTryを使用します。

エンドツーエンドの例

例外をスローするコードをTryで読み取り、ドメインエラーを扱うためにEitherへ変換し、最後に存在するかどうかだけを気にする呼び出し元のためにOptionへ変換します。

import scala.util.Try

object Main {
  def safeDiv(a: Int, b: Int): Option[Int] =
    Try(a / b).toEither.left.map(_ => "math error").toOption

  def main(args: Array[String]): Unit = {
    println(safeDiv(10, 2))
    println(safeDiv(10, 0))
  }
}

理解度チェック

変換に関する知識を確認しましょう。

まとめ

Option、Either、Tryの相互変換について学びました。

  • Option.toRight → Either、Either.toOption → Option。
  • Try.toOptionとTry.toEitherは、例外を値へ橋渡しします。
  • パイプラインは早い段階で1つのエラー型に正規化します。
  • 必要なエラー情報の量に合った型を選びます。

よくある質問

「型の相互変換」レッスンは無料ですか?

はい。「型の相互変換」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Scala for Backend Engineering & Functional Programmingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Scala for Backend Engineering & Functional Programmingコースには全4レッスンが含まれています。

「型の相互変換」で何を学びますか?

Option、Either、Try です。 ブラウザで直接実行するハンズオンコードでScala for Backend Engineering & Functional Programmingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Scala for Backend Engineering & Functional Programmingを始めるのに経験は必要ですか?

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

「型の相互変換」レッスンにはどのくらい時間がかかりますか?

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

このScala for Backend Engineering & Functional Programmingレッスンでコードを書いて実行できますか?

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

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

  1. エラーに対する Either
  2. Try、Success、Failure
  3. Either の合成
  4. 型の相互変換
← Scala for Backend Engineering & Functional Programmingに戻る