مقدمات سکالا 8 داده های جبری

scala
tutorial

#1

Algebraic Data Types
داده های جبری به دو دسته کلی تقسیم میشوند
۱. Sum Type (جمعی)
۲. Product Type (ضربی)

Sum Type
وقتی میخواهیم منطق برنامه رو طراحی کنیم گاهی به موردی بر میخوریم که یک تایپ تشکیل شده از چند تایپ دیگه به عبارت دیگه تایپ A یا B هست یا C
به این نوع داده های Sum Type (جمعی) گفته میشود

trait Color
case class Red() extends Color
case class Blue() extends Color

حالا هر تابعی که تایپه Color در آرگومان میگیره میتونه Red یا Blue هم بگیره چون Blue و Red هردو از تایپه Color هستند

بهتر کردن مثال بالا در ساخت داده های جبری بجای trait اگه از sealed trait استفاده کنیم compiler متوجه میشه که تنها حالت هایی که در این file بیان کردیم جزو sum هستند و درصورت هندل نکردن تمامه حالت ها بهمون خطا میده این کاربسیار مطلوبه چون هدف ما اینکه تمامه حالت های یک تایپ درست باهاش کار کنیم و توابع کامل داشته باشیم

sealed trait Color
case class Red() extends Color
case class Blue() extends Color

Product Type

گاهی یک تایپ چندین قسمت داره که هرکدام تایپه مختلفی هستش برای مثال A یک قسمت اسم String داره و یک قسمت سن Int
در واقع case class ها دقیقا همین نوع داده هستن

case class Student(name: String, age: Int)

استفاده از Sum و Product کنار هم

sealed trait Person {
  val name: String
}
case class Student(name: String, major: String) extends Person
case class GraduateStudent(name: String, major: String, researchSubject: String ) extends Person

یکی از ایده های مهم برنامه نویسی functional با تایپ اینکه با استفاده از تایپ ها برای برنامه یک زبان درست کنیم که درون حالت های غلط و غیر منطقی قابله بیان نباشه از دیده دیگری میشه به این زبان های کوچک به شکل ماشین حالات state machine نگاه کرد
فرض کنید از شما درخواست میکنن که برنامه بنویسید که برای ارتباط با کاربر یا از ایمیل استفاده بشه یا تلفن و نه هردو

اگر بخواهیم اینو در تایپ بیان کنیم بطوری که نشه حالت هردو هرگز رخ نده اینطوری مینویسیم

sealed trait ContactInfo
case class EmailOnly(email: String) extends ContactInfo
case class PhoneOnly(phoneNumber: Int) extends ContactInfo


def sendMessage(contactInfo : ContactInfo, message: String)

استفاده از ADT و parametrization برای ساخت داده های کلی

قدرت ADT ها فقط با برنامه های کوچک تمام نمیشه با استفاده از type parametrization میشه ساختار های بسیار قوی درست کرد
مثلا اگر بخواهیم ساختار داده درختی ایجاد کنیم با ADT به این شکل انجام میدیم

sealed trait Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
case class Leaf[A](value: A) extends Tree[A]

مقدمات سکالا
تا چه زمانی می توان از شرط های تو در تو استفاده کرد مانند case در الکسیر