มีปัญหาบางอย่างที่แก้ไขได้อย่างง่ายดายโดย Algebraic Data Types เช่น List type สามารถแสดงออกได้อย่างชัดเจนว่า:
data ConsList a = Empty | ConsCell a (ConsList a)
consmap f Empty = Empty
consmap f (ConsCell a b) = ConsCell (f a) (consmap f b)
l = ConsCell 1 (ConsCell 2 (ConsCell 3 Empty))
consmap (+1) l
ตัวอย่างเฉพาะนี้อยู่ใน Haskell แต่มันจะคล้ายกันในภาษาอื่นที่มีการสนับสนุนเนทิฟสำหรับประเภทข้อมูลพีชคณิต
ปรากฎว่ามีการแมปที่ชัดเจนกับการพิมพ์ย่อยสไตล์ OO: ประเภทข้อมูลจะกลายเป็นคลาสฐานนามธรรมและตัวสร้างข้อมูลทั้งหมดจะกลายเป็นคลาสย่อยที่เป็นรูปธรรม นี่คือตัวอย่างใน Scala:
sealed abstract class ConsList[+T] {
def map[U](f: T => U): ConsList[U]
}
object Empty extends ConsList[Nothing] {
override def map[U](f: Nothing => U) = this
}
final class ConsCell[T](first: T, rest: ConsList[T]) extends ConsList[T] {
override def map[U](f: T => U) = new ConsCell(f(first), rest.map(f))
}
val l = (new ConsCell(1, new ConsCell(2, new ConsCell(3, Empty)))
l.map(1+)
สิ่งเดียวที่จำเป็นนอกเหนือจากคลาสย่อยที่ไร้เดียงสาคือวิธีปิดคลาส
คุณจะแก้ไขปัญหานี้ด้วยภาษาเช่น C # หรือ Java อย่างไร บล็อกที่สะดุดสองข้อที่ฉันพบเมื่อพยายามใช้ Algebraic Data Types ใน C # คือ:
- ฉันไม่สามารถจำแนกประเภทด้านล่างที่เรียกใน C # (เช่นฉันไม่สามารถหาสิ่งที่จะใส่ลงไป
class Empty : ConsList< ??? >
) - ฉันไม่สามารถหาวิธีปิดผนึก
ConsList
เพื่อไม่ให้มีการเพิ่มคลาสย่อยลงในลำดับชั้น
อะไรจะเป็นวิธีที่ใช้สำนวนที่สุดในการใช้ประเภทข้อมูลพีชคณิตใน C # และ / หรือ Java หรือถ้ามันเป็นไปไม่ได้สิ่งที่จะเปลี่ยนสำนวน?