0Pricing
Scala for Backend Engineering & Functional Programming · บทเรียน

การประกอบ Either

map และ flatMap

การประกอบ Either เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

การประกอบการคำนวณ

โปรแกรมจริงมักต่อขั้นตอนที่อาจล้มเหลวหลายขั้น เช่น แปลงข้อมูล ตรวจสอบความถูกต้อง ค้นหา และคำนวณ Either ช่วยให้คุณประกอบขั้นตอนเหล่านี้เข้าด้วยกัน โดยความล้มเหลวแรกจะหยุดกระบวนการทั้งหมด

เครื่องมือที่ใช้คือ map, flatMap และนิพจน์ for

flatMap เรียง Either

flatMap ใช้ฟังก์ชันที่ตัวมันเองคืนค่าเป็น Either หากตัวรับเป็น Left ฟังก์ชันจะไม่ถูกเรียก และ Left จะถูกส่งต่อไป

object Main {
  def positive(n: Int): Either[String, Int] =
    if (n > 0) Right(n) else Left("not positive")

  def main(args: Array[String]): Unit = {
    val r = Right(5).flatMap(positive)
    val l = Right(-1).flatMap(positive)
    println(r)
    println(l)
  }
}

การหยุดก่อนกำหนด

เมื่อคุณต่อการเรียก flatMap หลายรายการ Left แรกจะหยุดการทำงานทั้งหมด ขั้นตอนถัดไปจะถูกข้าม และข้อผิดพลาดนั้นจะกลายเป็นผลลัพธ์สุดท้าย

object Main {
  def step(label: String, n: Int): Either[String, Int] = {
    println(s"running $label")
    Right(n + 1)
  }

  def main(args: Array[String]): Unit = {
    val result = Left("early error").asInstanceOf[Either[String, Int]]
      .flatMap(n => step("A", n))
      .flatMap(n => step("B", n))
    println(result)
  }
}

นิพจน์ for บน Either

เนื่องจาก Either ให้น้ำหนักกับ Right คุณจึงใช้กับนิพจน์ for ได้ เครื่องหมาย <- แต่ละรายการจะแกะค่า Right ออกมา ส่วน Left ใด ๆ จะหยุดนิพจน์และกลายเป็นผลลัพธ์

object Main {
  def parse(s: String): Either[String, Int] =
    s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val sum = for {
      a <- parse("3")
      b <- parse("4")
    } yield a + b
    println(sum)
  }
}

นิพจน์ for ที่ล้มเหลว

หากขั้นตอนใดในนิพจน์ให้ผลเป็น Left expression ทั้งหมดจะเป็น Left นั้น และขั้นตอนถัดไปจะไม่ทำงาน

object Main {
  def parse(s: String): Either[String, Int] =
    s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val sum = for {
      a <- parse("3")
      b <- parse("oops")
      c <- parse("5")
    } yield a + b + c
    println(sum)
  }
}

การต่อการตรวจสอบความถูกต้อง

กระบวนการต่อเนื่องที่ใช้งานจริง: แปลงสตริง จากนั้นตรวจสอบกฎทางธุรกิจ แล้วจึงแปลงผลลัพธ์ แต่ละขั้นจะคืนค่าเป็น Either

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight("not a number")
  def checkRange(n: Int): Either[String, Int] =
    if (n >= 1 && n <= 100) Right(n) else Left("out of range")

  def process(s: String): Either[String, Int] =
    parse(s).flatMap(checkRange).map(_ * 10)

  def main(args: Array[String]): Unit = {
    println(process("7"))
    println(process("500"))
    println(process("x"))
  }
}

map เทียบกับ flatMap

ใช้ map เมื่อฟังก์ชันของคุณคืนค่าเป็น ค่าทั่วไป ใช้ flatMap เมื่อฟังก์ชันคืนค่าเป็น Either อีกหนึ่งรายการ เพื่อหลีกเลี่ยง Either[String, Either[String, Int]] ที่ซ้อนกัน

@main def run(): Unit = {
  val withMap: Either[String, Int] = Right(2).map(_ + 1)
  val nested: Either[String, Either[String, Int]] = Right(2).map(n => Right(n + 1))
  val flat: Either[String, Int] = Right(2).flatMap(n => Right(n + 1))
  println(withMap)
  println(nested)
  println(flat)
}

การรวมค่าที่เป็นอิสระต่อกัน

นิพจน์ for ยังใช้ได้เมื่อแต่ละขั้นไม่ขึ้นต่อกับขั้นก่อนหน้า ทุกขั้นต้องสำเร็จเสียก่อนจึงจะทำงาน yield สุดท้าย

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight(s"bad: $s")

  def main(args: Array[String]): Unit = {
    val combined = for {
      x <- parse("10")
      y <- parse("20")
      z <- parse("30")
    } yield List(x, y, z).sum
    println(combined)
  }
}

การแปลงข้อผิดพลาดแบบ leftMap

ไลบรารีมาตรฐาน Either ไม่มี leftMap แต่คุณสามารถแปลงข้อผิดพลาดด้วย swap.map(...).swap หรือแมปภายใน fold ได้ วิธีนี้ช่วยให้ชนิดของข้อผิดพลาดสอดคล้องกันตลอดกระบวนการต่อเนื่อง

@main def run(): Unit = {
  val e: Either[String, Int] = Left("low-level error")
  val mapped = e.swap.map(msg => s"context: $msg").swap
  println(mapped)
}

นำทุกอย่างมารวมกัน

กระบวนการต่อเนื่องของเครื่องคิดเลขขนาดเล็กที่แปลงตัวเลขสองจำนวนแล้วหาร พร้อมรายงานความล้มเหลวแต่ละแบบเป็นข้อผิดพลาดที่มีชนิดระบุ

object Main {
  def parse(s: String): Either[String, Int] = s.toIntOption.toRight(s"bad number: $s")
  def divide(a: Int, b: Int): Either[String, Int] =
    if (b == 0) Left("division by zero") else Right(a / b)

  def calc(x: String, y: String): Either[String, Int] =
    for {
      a <- parse(x)
      b <- parse(y)
      r <- divide(a, b)
    } yield r

  def main(args: Array[String]): Unit = {
    println(calc("20", "4"))
    println(calc("20", "0"))
    println(calc("x", "4"))
  }
}

เหตุใดเรื่องนี้จึงสำคัญ

การประกอบ Either ทำให้เกิดแนวคิด การเขียนโปรแกรมตามราง: เส้นทางปกติจะไหลผ่าน Right ส่วนข้อผิดพลาดจะเบี่ยงไปยังราง Left และข้ามส่วนที่เหลือ ไม่ต้องใช้ข้อยกเว้น ไม่ต้องตรวจสอบค่าว่าง ใช้เพียงค่า

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับการประกอบ Either

สรุปทบทวน

คุณได้เรียนรู้การ ประกอบ Either แล้ว:

  • flatMap เรียงขั้นตอนที่อาจล้มเหลว และหยุดทันทีเมื่อพบ Left แรก
  • นิพจน์ for ช่วยให้อ่านกระบวนการหลายขั้นตอนได้อย่างสะอาด
  • ใช้ map กับผลลัพธ์ทั่วไป และใช้ flatMap กับฟังก์ชันที่คืนค่า Either
  • แปลงข้อผิดพลาดด้วย swap.map(...).swap

คำถามที่พบบ่อย

บทเรียน “การประกอบ Either” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การประกอบ Either” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การประกอบ Either”

map และ flatMap คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การประกอบ Either” ใช้เวลานานแค่ไหน

บทเรียน 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