การประกอบ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Either สำหรับข้อผิดพลาด
- Try, Success, Failure
- การประกอบ Either
- การแปลงระหว่างชนิด