Ada beberapa masalah yang mudah dipecahkan oleh Tipe Data Aljabar, misalnya tipe Daftar dapat dengan sangat ringkas dinyatakan sebagai:
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
Contoh khusus ini ada di Haskell, tetapi akan serupa dalam bahasa lain dengan dukungan asli untuk Tipe Data Aljabar.
Ternyata ada pemetaan yang jelas untuk subtipe gaya OO: tipe data menjadi kelas dasar abstrak dan setiap konstruktor data menjadi subkelas beton. Berikut ini contoh dalam 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+)
Satu-satunya hal yang diperlukan di luar subclass naif adalah cara untuk menyegel kelas, yaitu cara untuk membuatnya mustahil untuk menambahkan subclass ke hierarki.
Bagaimana Anda mendekati masalah ini dalam bahasa seperti C # atau Java? Dua batu sandungan yang saya temukan ketika mencoba menggunakan Tipe Data Aljabar di C # adalah:
- Saya tidak tahu apa yang disebut tipe bawah di C # (yaitu saya tidak tahu apa yang harus dimasukkan ke dalam
class Empty : ConsList< ??? >
) - Saya tidak bisa menemukan cara untuk menutup
ConsList
sehingga tidak ada subclass yang dapat ditambahkan ke hierarki
Apa yang akan menjadi cara paling idiomatis untuk mengimplementasikan Tipe Data Aljabar di C # dan / atau Java? Atau, jika itu tidak mungkin, apa yang akan menjadi pengganti idiomatik?