Saya tidak memiliki jawaban lengkap 100%, tetapi saya memiliki sebuah pointer yang mungkin cukup untuk Anda.
Kompilator Scala menangani GADT (Generalized Algebraic Data Type) dengan cara yang sangat khusus. Beberapa kasus diselesaikan dengan penanganan khusus, beberapa kasus tidak terpecahkan. Dotty sedang mencoba untuk mengisi sebagian besar lubang, dan telah menyelesaikan banyak masalah terkait, namun masih ada beberapa yang terbuka juga.
Contoh umum penanganan GADT khusus dalam kompiler Scala 2 sangat terkait dengan use case Anda. Jika kita melihat:
def method[A](arg: Base[A]) = {
arg match {
case Derived(_) => 42
}
}
dan kami secara eksplisit mendeklarasikan tipe pengembalian menjadi A
:
def method[A](arg: Base[A]): A
itu akan mengkompilasi dengan baik. IDE Anda mungkin mengeluh, tetapi kompiler akan membiarkannya lewat. Metode mengatakan mengembalikan sebuah A
, tetapi kasus pencocokan pola mengevaluasi menjadi Int
, yang secara teoritis tidak boleh dikompilasi. Namun, penanganan khusus GADT di kompiler mengatakan tidak apa-apa, karena dalam cabang pencocokan pola tertentu A
telah "diperbaiki" menjadi Int
(karena kami cocok dengan Derived
yang a Base[Int]
).
Parameter tipe umum untuk GADT (dalam kasus kami A
) harus dinyatakan di suatu tempat. Dan inilah bagian yang menarik - penanganan kompiler khusus hanya berfungsi ketika dideklarasikan sebagai parameter tipe dari metode penutup . Jika itu berasal dari anggota tipe atau parameter tipe dari sifat / kelas terlampir, itu tidak dapat dikompilasi, seperti yang Anda saksikan sendiri.
Inilah sebabnya saya mengatakan itu bukan jawaban lengkap 100% - Saya tidak bisa menunjuk ke tempat konkret (seperti spesifikasi resmi) yang mendokumentasikan ini dengan benar. Sumber tentang penanganan GADT di Scala berasal dari beberapa blogpost , yang bagus, tetapi jika Anda menginginkan lebih dari itu, Anda harus menggali sendiri kode kompiler. Saya mencoba melakukan hal itu, dan saya pikir ini berkaitan dengan metode ini , tetapi jika Anda benar-benar ingin masuk lebih dalam, Anda mungkin ingin melakukan ping ke seseorang yang lebih berpengalaman dengan basis kode penyusun Scala.