Arrow Raise DSL: การประกอบข้อผิดพลาดแบบมีชนิด
ใช้บริบท Raise ของ Arrow และ raise() เพื่อประกอบลำดับการทำงานที่มีข้อผิดพลาดหลายรายการอย่างเป็นระเบียบ
Arrow Raise DSL: การประกอบข้อผิดพลาดแบบมีชนิด เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
ข้อจำกัดของการเชื่อม Either
การเชื่อม Either ด้วย flatMap จะสร้างแลมบ์ดาที่ซ้อนกันลึกเมื่อมีการดำเนินการต่อเนื่องหลายขั้นตอน Raise DSL ของ Arrow (เริ่มมีใน Arrow 1.2) จึงมีรูปแบบไวยากรณ์ที่สะอาดกว่าและคล้ายโครูทีน โดยใช้ context receiver หรือฟังก์ชันส่วนขยายของ Kotlin
Raise<E> คืออะไร
Raise เป็นบริบทที่สามารถ raise (หยุดการทำงานทันทีพร้อมส่งต่อ) ข้อผิดพลาดชนิด E ได้ ฟังก์ชันที่อาจล้มเหลวจะเรียก raise(error) เพื่อยกเลิกและส่งต่อข้อผิดพลาด ซึ่งคล้ายกับการโยนข้อยกเว้นแต่ไม่ใช้ข้อยกเว้น
ตัวสร้าง either { }
ตัวสร้าง either { } จะสร้าง Either จากบล็อกที่มี Raise อยู่ในขอบเขต ภายในบล็อก ให้เรียก raise(error) เมื่อล้มเหลว หรือคืนค่าโดยตรงเมื่อสำเร็จ:
import arrow.core.raise.either
import arrow.core.raise.Raise
fun validateAge(age: Int): Either<String, Int> = either {
if (age < 0) raise("Age cannot be negative")
if (age > 150) raise("Age too large")
age
}bind() — แกะค่า Either ภายใน either{}
ภายในบล็อก either { } ให้เรียก .bind() กับค่า Either ใด ๆ เพื่อแกะค่าออกมา หากค่านั้นเป็น Left bind() จะเรียก raise และหยุดบล็อกทันทีโดยอัตโนมัติ:
fun createUser(name: String, age: Int): Either<String, User> = either {
val validName = validateName(name).bind() // raises if Left
val validAge = validateAge(age).bind() // raises if Left
User(validName, validAge) // only reached if both succeed
}ensure() — ตรวจสอบเงื่อนไขแบบแทรกในบรรทัด
ensure(condition) { error } เป็นรูปแบบย่อของ if (!condition) raise(error) ช่วยให้ตรรกะการตรวจสอบกระชับ:
fun validateEmail(email: String): Either<String, String> = either {
ensure(email.contains("@")) { "Email must contain @" }
ensure(email.length <= 255) { "Email too long" }
email
}ensureNotNull() — ตรวจสอบค่าว่างด้วย Raise
ensureNotNull(value) { error } จะแกะค่าที่อาจเป็นค่าว่างออกมา หรือเรียก raise หากค่านั้นเป็นค่าว่าง:
fun findUser(id: Long, repo: UserRepo): Either<UserError, User> = either {
ensureNotNull(repo.findById(id)) { UserError.NotFound(id) }
}Raise ด้วย Context Receiver (Arrow 1.2 ขึ้นไป)
คุณสามารถประกาศฟังก์ชันที่ต้องการบริบท Raise ได้โดยตรง โดยไม่ต้องห่อฟังก์ชันด้วย either { }:
context(Raise<String>)
fun requirePositive(n: Int): Int {
ensure(n > 0) { "Must be positive" }
return n
}
// Called inside either { }
val result = either { requirePositive(-1) } // Left("Must be positive")การสะสมข้อผิดพลาดด้วย zipOrAccumulate
ตามค่าเริ่มต้น Raise จะหยุดทำงานเมื่อพบข้อผิดพลาดแรก ใช้ zipOrAccumulate() เพื่อเรียกใช้การตรวจสอบหลายรายการและรวบรวมข้อผิดพลาดทั้งหมดไว้ใน NonEmptyList:
val result: Either<NonEmptyList<String>, User> = either {
zipOrAccumulate(
{ validateName(name).bind() },
{ validateAge(age).bind() }
) { validName, validAge -> User(validName, validAge) }
}recover { } — การจัดการข้อผิดพลาดเฉพาะรายการ
ใช้ recover { error -> ... } ภายใน either { } เพื่อจัดการข้อผิดพลาดที่ถูก raise เฉพาะรายการและกำหนดค่า fallback จากนั้นจึงทำการคำนวณต่อ:
val name: String = either {
findUser(0L).bind().name
}.recover { error ->
if (error == UserError.NotFound) "Guest" else raise(error)
}.getOrNull() ?: "Guest"Raise เทียบกับการเชื่อม Either: ควรใช้แบบใด
ใช้ either { }.bind() สำหรับลำดับการทำงานเชิงเส้นที่มีหลายขั้นตอนต่อเนื่อง เพราะอ่านได้เหมือนโค้ดเชิงคำสั่งแต่ยังคงบริสุทธิ์ ใช้การเชื่อมด้วย flatMap สำหรับองค์ประกอบสั้น ๆ สองขั้นตอน หรือเมื่อต้องเชื่อมกับไลบรารีเชิงฟังก์ชันอื่น
การทดสอบฟังก์ชันที่ใช้ Raise
ทดสอบโดยเรียกฟังก์ชันภายใน either { } แล้วตรวจสอบผลลัพธ์ ตัวจับคู่ของ Kotest อย่าง shouldBeLeft() และ shouldBeRight() ใน Arrow ช่วยให้การตรวจสอบกระชับ:
import arrow.core.shouldBeLeft
import arrow.core.shouldBeRight
@Test
fun `negative age returns Left`() {
validateAge(-1).shouldBeLeft()
}
@Test
fun `valid age returns Right`() {
validateAge(25).shouldBeRight(25)
}ตรวจสอบความเข้าใจ
ภายในบล็อก either { } การเรียก .bind() กับค่า Either.Left จะทำอะไร
สรุป: Arrow Raise DSL
ประเด็นสำคัญ:
either { }สร้างEitherจากบล็อกที่มีRaiseอยู่ในขอบเขต.bind()แกะค่าEitherและหยุดการทำงานทันทีเมื่อพบLeftensure(condition) { error }และensureNotNull(value) { error }ใช้สำหรับการตรวจสอบแบบแทรกในบรรทัดzipOrAccumulate()ใช้รวบรวมข้อผิดพลาดหลายรายการแทนการหยุดทำงานทันที- อ่านได้เหมือนโค้ดเชิงคำสั่ง แต่ยังคงเป็นฟังก์ชันบริสุทธิ์
คำถามที่พบบ่อย
บทเรียน “Arrow Raise DSL: การประกอบข้อผิดพลาดแบบมีชนิด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “Arrow Raise DSL: การประกอบข้อผิดพลาดแบบมีชนิด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “Arrow Raise DSL: การประกอบข้อผิดพลาดแบบมีชนิด”
ใช้บริบท Raise ของ Arrow และ raise() เพื่อประกอบลำดับการทำงานที่มีข้อผิดพลาดหลายรายการอย่างเป็นระเบียบ คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “Arrow Raise DSL: การประกอบข้อผิดพลาดแบบมีชนิด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม
ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- Either : การจัดการข้อผิดพลาดตามชนิดโดยไม่ใช้ Exception
- Arrow Raise DSL: การประกอบข้อผิดพลาดแบบมีชนิด
- Option และ Nullable: ควรใช้แต่ละแบบเมื่อใด
- การสร้างแบบจำลองโดเมนเชิงฟังก์ชันด้วยชนิดหลักของ Arrow