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

ทำความเข้าใจ Monads ใน Scala

ทำให้ Monads เข้าใจได้ง่ายขึ้น และเรียนรู้ว่า Monads ช่วยให้ประกอบการคำนวณตามลำดับในรูปแบบเชิงฟังก์ชันได้อย่างไร

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

Monad คืออะไร

Monad เป็นแนวคิดพื้นฐานในการเขียนโปรแกรมเชิงฟังก์ชัน และมักถือว่าเป็นหัวข้อขั้นสูง ไม่ต้องกังวล เราจะทำให้แนวคิดนี้เข้าใจได้ง่ายขึ้น!

โดยแก่นแล้ว Monad คือรูปแบบการออกแบบที่ช่วยจัดลำดับการคำนวณซึ่งเกี่ยวข้องกับ "บริบท" ลองนึกถึง Monad ว่าเป็นวิธีจัดการผลข้างเคียงหรือค่าที่อาจขาดหายไป ภายในโครงสร้างที่คาดเดาได้

การเชื่อมโยงการดำเนินการตามบริบท

ลองนึกภาพว่าคุณมีค่าที่อาจมีอยู่หรือไม่มีก็ได้ เช่น Option[Int] หากต้องการดำเนินการหลายอย่างกับค่านั้น แต่ทำเฉพาะเมื่อค่ามีอยู่ คุณจะทำอย่างไรให้โค้ดสะอาด

คำสั่ง if ที่ซ้อนกันจะยุ่งเหยิงอย่างรวดเร็ว Monad จึงมอบวิธีที่สะอาดและเป็นลำดับสำหรับเชื่อมโยงการดำเนินการเหล่านี้ พร้อมส่งต่อ "บริบท" เช่น การมีค่าหรือไม่มีค่าโดยอัตโนมัติ

พลังของ `flatMap`

การดำเนินการที่สำคัญที่สุดสำหรับทำความเข้าใจ Monad คือ flatMap

  • รับฟังก์ชันที่คืนค่าอีกค่าหนึ่งซึ่งอยู่ในบริบท เช่น Option หรือ List
  • ใช้ฟังก์ชันนี้กับค่าที่อยู่ ภายในบริบทปัจจุบัน
  • หากบริบทว่างเปล่า เช่น None flatMap จะส่งต่อความว่างเปล่านั้นโดยไม่ใช้ฟังก์ชัน

วิธีนี้ช่วยให้คุณเชื่อมโยงการดำเนินการได้อย่างราบรื่น พร้อมจัดการความล้มเหลวที่อาจเกิดขึ้นหรือค่าที่ขาดหายไประหว่างทาง

`Option` และ `flatMap`

ชนิดข้อมูล Option ของ Scala เป็นตัวอย่างที่สมบูรณ์แบบของ Monad Option อาจเป็น Some(value) หรือ None

เมื่อคุณใช้ flatMap กับ Option:

  • หากเป็น Some(value) ฟังก์ชันที่คุณระบุจะถูกใช้กับ value และนำผลลัพธ์ของมัน ซึ่งเป็น Option อีกตัวหนึ่งมาใช้
  • หากเป็น None ฟังก์ชันจะไม่ถูกเรียกใช้ และคืนค่า None โดยตรง

วิธีนี้ช่วยให้มั่นใจว่าการดำเนินการจะทำงานก็ต่อเมื่อมีค่าจริงเท่านั้น

`flatMap` กับ `Option`

มาดูการทำงานของ flatMap กับ Option กัน โค้ดนี้พยายามแปลงสตริงเป็นจำนวนเต็ม แล้วคูณด้วยสอง แต่จะทำก็ต่อเมื่อทั้งสองขั้นตอนสำเร็จ

object Main {
  def parseToInt(s: String): Option[Int] =
    try {
      Some(s.toInt)
    } catch {
      case _: NumberFormatException => None
    }

  def main(args: Array[String]): Unit = {
    val result1 = parseToInt("10").flatMap(x => Some(x * 2))
    val result2 = parseToInt("hello").flatMap(x => Some(x * 2))

    println(s"Result 1: $result1")
    println(s"Result 2: $result2")
  }
}

`List` และ `flatMap`

ชนิดข้อมูล Scala อีกชนิดหนึ่งที่ทำงานเสมือน Monad คือ List

เมื่อคุณใช้ flatMap กับ List:

  • ใช้ฟังก์ชันที่กำหนดกับสมาชิกแต่ละตัวในรายการ
  • ฟังก์ชันต้องคืนค่า List ใหม่สำหรับสมาชิกแต่ละตัว
  • จากนั้นนำรายการผลลัพธ์ทั้งหมดมาต่อกันเป็นรายการเดียวที่ถูกคลี่ออก

วิธีนี้มีประโยชน์สำหรับการแปลงและรวมรายการข้อมูล

`flatMap` กับ `List`

นี่คือวิธีที่ flatMap ทำงานกับ List โปรดสังเกตว่าผลลัพธ์จากการใช้ฟังก์ชันที่คืนรายการสำหรับแต่ละสมาชิกถูก "คลี่ออก" อย่างไร

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3)

    // For each number, create a list of that number and its double
    val result = numbers.flatMap(n => List(n, n * 2))

    println(s"Original: $numbers")
    println(s"FlatMapped: $result")

    val words = List("hello", "world")
    val chars = words.flatMap(_.toList) // Get all characters

    println(s"Words: $words")
    println(s"Chars: $chars")
  }
}

กฎของ Monad (ฉบับย่อ)

แม้ว่า flatMap จะเป็นการดำเนินการหลัก แต่ Monad ที่แท้จริงยังต้องปฏิบัติตามกฎบางประการเพื่อให้มีพฤติกรรมที่คาดเดาได้

พูดง่าย ๆ ชนิดข้อมูลจะเป็นแบบ monadic หากมีคุณสมบัติดังนี้:

  • สามารถ "ห่อหุ้ม" ค่าได้ ซึ่งมักเรียกว่า pure หรือ unit
  • มีการดำเนินการ flatMap ที่เชื่อมโยงการคำนวณโดยรักษาบริบทไว้

กฎเหล่านี้ช่วยให้มั่นใจว่าการประกอบการดำเนินการแบบ monadic มีความสอดคล้องกัน ไม่ว่าคุณจะจัดกลุ่มการดำเนินการอย่างไร

Monad และการเขียนแบบ For

การเขียนแบบ for-comprehensions ของ Scala เป็นไวยากรณ์ย่อสำหรับทำงานกับ Monad และชนิดข้อมูลอื่น ๆ เช่น ฟังก์เตอร์และแอปพลิเคทีฟ

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

เบื้องหลัง คอมไพเลอร์ Scala จะแปลง for-comprehensions ให้เป็นชุดการเรียก flatMap, map และ filter

`Option` ในการเขียนแบบ For

ตัวอย่างนี้แสดงให้เห็นว่าการเขียนแบบ for-comprehension ช่วยลดความซับซ้อนของสายการเรียก Option.flatMap จากก่อนหน้านี้ได้อย่างไร โดยจะจัดการกรณี None ให้โดยอัตโนมัติ

object Main {
  def parseToInt(s: String): Option[Int] =
    try {
      Some(s.toInt)
    } catch {
      case _: NumberFormatException => None
    }

  def main(args: Array[String]): Unit = {
    val numStr1 = "10"
    val numStr2 = "5"
    val badStr = "abc"

    val result1 = for {
      a <- parseToInt(numStr1) // If parseToInt returns None, the whole for-comp becomes None
      b <- parseToInt(numStr2)
    } yield a + b

    val result2 = for {
      a <- parseToInt(numStr1)
      b <- parseToInt(badStr) // This will be None
    } yield a + b

    println(s"Sum 1: $result1") // Some(15)
    println(s"Sum 2: $result2") // None
  }
}

โจทย์ท้าทายเรื่อง Monad

พิจารณาโค้ด Scala ต่อไปนี้

val list1 = List(1, 2)
val list2 = List(10, 20)

val result = for {
  x <- list1
  y <- list2
} yield x * y

Monad: การจัดลำดับตามบริบท

ยินดีด้วย! คุณได้ก้าวสำคัญในการทำความเข้าใจ Monad

  • Monad มอบรูปแบบอันทรงพลังสำหรับจัดลำดับการคำนวณที่ทำงานอยู่ภายใน "บริบท" เช่น Option สำหรับการมีหรือไม่มีค่า และ List สำหรับค่าหลายค่า
  • การดำเนินการสำคัญคือ flatMap ซึ่งใช้ฟังก์ชันที่คืนค่าบริบทใหม่ ทำให้สามารถเชื่อมโยงและคลี่บริบทออกได้อย่างมีประสิทธิภาพ
  • การเขียนแบบ for-comprehensions ของ Scala เป็นไวยากรณ์ย่อที่ยอดเยี่ยม โดยแปลงเป็นการเรียก flatMap และ map/filter โดยตรง ทำให้โค้ดแบบ monadic อ่านง่ายขึ้นมาก

ต่อไป เราจะสำรวจไลบรารีการเขียนโปรแกรมเชิงฟังก์ชันยอดนิยมอย่าง Cats และ ZIO ซึ่งใช้แนวคิดแบบ monadic เหล่านี้อย่างกว้างขวาง

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

บทเรียน “ทำความเข้าใจ Monads ใน Scala” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ทำความเข้าใจ Monads ใน Scala”

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

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

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

บทเรียน “ทำความเข้าใจ Monads ใน Scala” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม

ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. บทนำสู่ Functors และ Applicatives
  2. ทำความเข้าใจ Monads ใน Scala
  3. สำรวจ Cats และ ZIO
← กลับไปที่ Scala for Backend Engineering & Functional Programming