ทำความเข้าใจ 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 - ใช้ฟังก์ชันนี้กับค่าที่อยู่ ภายในบริบทปัจจุบัน
- หากบริบทว่างเปล่า เช่น
NoneflatMapจะส่งต่อความว่างเปล่านั้นโดยไม่ใช้ฟังก์ชัน
วิธีนี้ช่วยให้คุณเชื่อมโยงการดำเนินการได้อย่างราบรื่น พร้อมจัดการความล้มเหลวที่อาจเกิดขึ้นหรือค่าที่ขาดหายไประหว่างทาง
`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 * yMonad: การจัดลำดับตามบริบท
ยินดีด้วย! คุณได้ก้าวสำคัญในการทำความเข้าใจ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- บทนำสู่ Functors และ Applicatives
- ทำความเข้าใจ Monads ใน Scala
- สำรวจ Cats และ ZIO