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

for 内の Option

Option を連鎖させます。

「for 内の Option」は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レッスンが含まれています。

Optionsをきれいにチェーンする

複数のflatMapやmapの呼び出しをチェーンすると、読みにくくなることがあります。Scalaのfor-comprehensionを使うと、同じ処理をより簡潔な構文で書けます。

これは、コンパイラーがflatMapやmapの呼び出しに書き換える糖衣構文です。

基本的なfor-comprehension

for { ... } yield ...の中では、それぞれのx <- optionが、値が存在する場合にその値を取り出します。yieldが最終結果を作ります。

すべてのOptionがSomeなら、結果を格納したSomeが得られます。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val sum = for {
      x <- a
      y <- b
    } yield x + y
    println(sum)
  }
}

Noneでの短絡

いずれかのジェネレーターがNoneの場合、for-comprehension全体の結果はNoneになります。残りのステップはスキップされます。

これはflatMapによる短絡と同じ動作ですが、より読みやすく書けます。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = None
    val sum = for {
      x <- a
      y <- b
    } yield x + y
    println(sum)
  }
}

糖衣構文の展開方法

コンパイラーはfor-comprehensionをflatMapとmapに書き換えます。この2つのコードは同等です。

この仕組みを理解すると、結果の型を予測しやすくなります。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val viaFor = for { x <- a; y <- b } yield x + y
    val viaFlatMap = a.flatMap(x => b.map(y => x + y))
    println(viaFor)
    println(viaFlatMap)
  }
}

前の値を使う

後のジェネレーターから、前に束縛した値を参照できます。これにより、各ステップを前のステップに依存させられます。

object Main {
  def main(args: Array[String]): Unit = {
    val base: Option[Int] = Some(10)
    val result = for {
      x <- base
      y <- Some(x * 2)
    } yield x + y
    println(result)
  }
}

中間バインディング

=(矢印は不要)を使うと、for-comprehensionの中で通常の値を導入できます。中間計算に便利です。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(6)
    val result = for {
      x <- a
      doubled = x * 2
    } yield doubled + 1
    println(result)
  }
}

ifによるガード

for-comprehensionにはifフィルターを含められます。条件を満たさない場合、結果はNoneになります。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(8)
    val even = for {
      x <- a
      if x % 2 == 0
    } yield x
    println(even)
    val b: Option[Int] = Some(7)
    println(for { x <- b if x % 2 == 0 } yield x)
  }
}

検索結果の組み合わせ

よくある使い方は、複数のキーを検索し、すべてが存在する場合にだけ組み合わせることです。

object Main {
  val data = Map("a" -> 1, "b" -> 2)
  def main(args: Array[String]): Unit = {
    val combined = for {
      x <- data.get("a")
      y <- data.get("b")
    } yield x + y
    println(combined)
    val missing = for {
      x <- data.get("a")
      z <- data.get("c")
    } yield x + z
    println(missing)
  }
}

for-comprehensionを使う理由

次の利点があります。

  • 依存するOptionsを読みやすく順番に処理できる
  • Noneで自動的に短絡する
  • flatMap/mapと同じ能力を、より平坦な構文で使える
  • ifによるフィルタリングと、中間=バインディングを使える

値に変換する

for-comprehensionの結果はOptionなので、通常の値を得るにはgetOrElseまたはfoldで仕上げます。

object Main {
  def main(args: Array[String]): Unit = {
    val a: Option[Int] = Some(3)
    val b: Option[Int] = Some(4)
    val total = (for { x <- a; y <- b } yield x + y).getOrElse(0)
    println(total)
  }
}

組み合わせて使う

完全なパイプラインの例です。2つの入力を解析し、条件を検証して組み合わせ、デフォルト値を指定します。

object Main {
  def parse(s: String): Option[Int] = s.toIntOption
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- parse("10")
      y <- parse("5")
      if y != 0
    } yield x / y
    println(result.getOrElse(-1))
  }
}

理解度チェック

Optionに対するfor-comprehensionの理解度を確認しましょう。

まとめ

for-comprehensionを使ってOptionsをチェーンする方法を学びました。

  • for { x <- a; y <- b } yield ...はOptionsを読みやすく順番に処理します
  • flatMap/mapに展開されます
  • いずれかのNoneによって、全体の結果がNoneに短絡します
  • 後のジェネレーターでは前の値を使えます。=はバインディングを追加し、ifはフィルターになります
  • 通常の値を得るにはgetOrElseまたはfoldで仕上げます

よくある質問

「for 内の Option」レッスンは無料ですか?

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

「for 内の Option」で何を学びますか?

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

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

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

「for 内の Option」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

  1. null を避ける
  2. Option の map と flatMap
  3. getOrElse と fold
  4. for 内の Option
← Scala for Backend Engineering & Functional Programmingに戻る