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

ชนิดข้อมูลเชิงพีชคณิต

จำลองโดเมนของคุณ

บทเรียน 3 จาก 413 ขั้นตอน

ชนิดข้อมูลเชิงพีชคณิต เป็นบทเรียน 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 บทเรียน

ADT คืออะไร

ชนิดข้อมูลเชิงพีชคณิต (ADT) คือชนิดข้อมูลที่สร้างจากการนำชนิดอื่นมาประกอบกัน ใน Scala คุณสร้างแบบจำลอง ADT ด้วย sealed trait ร่วมกับรูปแบบย่อยที่เป็น case class และ case object

ADT ช่วยให้คุณอธิบายโครงสร้างของข้อมูลในโดเมนได้อย่างแม่นยำ

ชนิดผลรวม

ชนิดผลรวม หมายถึงค่าหนึ่งค่าจะเป็นหนึ่งในตัวเลือกหลายแบบ (เป็น OR) สัญญาณไฟจราจรอาจเป็นสีแดง OR สีเหลือง OR สีเขียว

คุณแสดงแนวคิดนี้ด้วย trait แบบ sealed และรูปแบบย่อยหลายแบบ

sealed trait Light
case object Red extends Light
case object Yellow extends Light
case object Green extends Light
object Main {
  def main(args: Array[String]): Unit = {
    val l: Light = Yellow
    println(l)
  }
}

ชนิดผลคูณ

ชนิดผลคูณ หมายถึงค่าหนึ่งค่าประกอบด้วยหลายฟิลด์ (เป็น AND) จุดหนึ่งจุดมีทั้งพิกัด x AND พิกัด y

คลาสแบบ case เป็นชนิดผลคูณ

case class Point(x: Int, y: Int)
object Main {
  def main(args: Array[String]): Unit = {
    val p = Point(3, 4)
    println(s"${p.x} and ${p.y}")
  }
}

รวมชนิดผลรวมกับชนิดผลคูณ

ADT จริงมักผสมทั้งสองแบบเข้าด้วยกัน ได้แก่ trait แบบ sealed (ผลรวม) ซึ่งมีรูปแบบย่อยเป็นคลาสแบบ case (ผลคูณ)

ในที่นี้ Shape อาจเป็น Circle (มีรัศมี) OR Rectangle (มีความกว้างและความสูง)

sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(w: Double, h: Double) extends Shape
object Main {
  def main(args: Array[String]): Unit = {
    val s: Shape = Rectangle(3, 4)
    println(s)
  }
}

ดำเนินการกับ ADT

คุณประมวลผล ADT ด้วยการจับคู่รูปแบบบนรูปแบบย่อย โดยแต่ละแขนงจะจัดการกับรูปร่างหนึ่งแบบ

sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(w: Double, h: Double) extends Shape
object Main {
  def area(s: Shape): Double = s match {
    case Circle(r)       => 3.14159 * r * r
    case Rectangle(w, h) => w * h
  }
  def main(args: Array[String]): Unit = {
    println(area(Circle(2)))
    println(area(Rectangle(3, 4)))
  }
}

สร้างแบบจำลองโดเมน

ADT ทำให้สถานะที่ไม่ถูกต้องไม่สามารถแสดงแทนได้ คุณสามารถสร้างแบบจำลองวิธีการชำระเงินให้เป็นชุดตัวเลือกที่ถูกต้องและปิดไว้

sealed trait PaymentMethod
case class CreditCard(number: String) extends PaymentMethod
case class BankTransfer(iban: String) extends PaymentMethod
case object Cash extends PaymentMethod
object Main {
  def main(args: Array[String]): Unit = {
    val m: PaymentMethod = Cash
    println(m)
  }
}

ADT แบบเวียนเกิด

ADT สามารถอ้างอิงถึงตัวเองได้ ซึ่งเป็นวิธีสร้างแบบจำลองต้นไม้และรายการ ในที่นี้คือต้นไม้ไบนารีอย่างง่าย

sealed trait Tree
case object Leaf extends Tree
case class Node(value: Int, left: Tree, right: Tree) extends Tree
object Main {
  def main(args: Array[String]): Unit = {
    val t: Tree = Node(1, Leaf, Node(2, Leaf, Leaf))
    println(t)
  }
}

พับ ADT แบบเวียนเกิด

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

sealed trait Tree
case object Leaf extends Tree
case class Node(value: Int, left: Tree, right: Tree) extends Tree
object Main {
  def sum(t: Tree): Int = t match {
    case Leaf            => 0
    case Node(v, l, r)   => v + sum(l) + sum(r)
  }
  def main(args: Array[String]): Unit = {
    val t = Node(1, Node(2, Leaf, Leaf), Node(3, Leaf, Leaf))
    println(sum(t))
  }
}

ทำไมต้องใช้ ADT

ADT มีประโยชน์มากเพราะสามารถ:

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

ADT เทียบกับการสืบทอด

การเขียนโปรแกรมเชิงวัตถุแบบดั้งเดิมจะกระจายพฤติกรรมไปตามคลาสย่อย ส่วน ADT จะปิดคำจำกัดความของข้อมูลไว้ และใส่พฤติกรรมไว้ในฟังก์ชันที่จับคู่รูปแบบ

การแยกข้อมูลออกจากพฤติกรรมเช่นนี้เป็นลักษณะสำคัญของการออกแบบเชิงฟังก์ชัน

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

ADT ขนาดเล็กที่สมบูรณ์ พร้อมฟังก์ชันซึ่งจัดการรูปแบบย่อยทุกแบบ

sealed trait Json
case class JNum(n: Double) extends Json
case class JStr(s: String) extends Json
case object JNull extends Json
object Main {
  def render(j: Json): String = j match {
    case JNum(n) => n.toString
    case JStr(s) => "\"" + s + "\""
    case JNull   => "null"
  }
  def main(args: Array[String]): Unit = {
    List(JNum(3.0), JStr("hi"), JNull).foreach(j => println(render(j)))
  }
}

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

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

สรุปทบทวน

คุณได้เรียนรู้การสร้างชนิดข้อมูลเชิงพีชคณิต:

  • ชนิดผลรวม: trait แบบ sealed ที่มีรูปแบบย่อยหลายแบบ (OR)
  • ชนิดผลคูณ: คลาสแบบ case ที่มีฟิลด์ (AND)
  • นำทั้งสองแบบมารวมกันเพื่อสร้างแบบจำลองโดเมนอย่างแม่นยำ
  • ADT สามารถเป็นแบบเวียนเกิดได้ (ต้นไม้ รายการ)
  • ประมวลผล ADT ด้วยการจับคู่รูปแบบ
เริ่มต้นได้ฟรี

เรียนรู้ Scala ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
39
บทเรียน
143

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

บทเรียน “ชนิดข้อมูลเชิงพีชคณิต” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ชนิดข้อมูลเชิงพีชคณิต”

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

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

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

บทเรียน “ชนิดข้อมูลเชิงพีชคณิต” ใช้เวลานานแค่ไหน

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

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

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

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

  1. คลาส Case
  2. Trait แบบปิดผนึก
  3. ชนิดข้อมูลเชิงพีชคณิต
  4. การจับคู่ที่ครบถ้วน
← กลับไปที่ Scala for Backend Engineering & Functional Programming