ฉันไม่มีคำตอบที่สมบูรณ์ 100% แต่ฉันมีตัวชี้ที่อาจเพียงพอสำหรับคุณ
คอมไพเลอร์ Scala เกี่ยวข้องกับ GADTs (ประเภทข้อมูลพีชคณิตทั่วไป) ในวิธีที่เฉพาะเจาะจงมาก บางกรณีแก้ไขได้ด้วยการจัดการพิเศษบางกรณีไม่ได้รับการแก้ไข บ้า ๆ บอ ๆ พยายามที่จะเติมเต็มที่สุดของหลุมและก็มีอยู่แล้วการแก้ไขปัญหามากที่เกี่ยวข้อง แต่ยังคงมีค่อนข้างน้อยเปิดคนได้เป็นอย่างดี
ตัวอย่างทั่วไปของการจัดการ GADT พิเศษในคอมไพเลอร์ Scala 2 นั้นเกี่ยวข้องกับกรณีการใช้งานของคุณมาก ถ้าเราดูที่:
def method[A](arg: Base[A]) = {
arg match {
case Derived(_) => 42
}
}
และเราประกาศประเภทการส่งคืนอย่างชัดเจนว่าเป็นA
:
def method[A](arg: Base[A]): A
มันจะรวบรวมได้ดี IDE ของคุณอาจบ่น แต่คอมไพเลอร์จะปล่อยให้ผ่าน Method บอกว่ามันจะคืนค่าA
แต่กรณีที่จับคู่รูปแบบจะประเมินเป็นอันInt
ซึ่งในทางทฤษฎีไม่ควรรวบรวม อย่างไรก็ตามการจัดการแบบพิเศษของ GADT ในคอมไพเลอร์กล่าวว่าใช้ได้เพราะในการจับคู่รูปแบบที่เฉพาะเจาะจงA
นั้นได้รับการ "แก้ไข" ให้เป็นInt
(เพราะเราจับคู่Derived
ซึ่งเป็น a Base[Int]
)
พารามิเตอร์ประเภททั่วไปสำหรับ GADT (ในกรณีของเราA
) จะต้องมีการประกาศที่ไหนสักแห่ง และนี่คือส่วนหนึ่งที่น่าสนใจ - การจัดการคอมไพเลอร์พิเศษใช้งานได้เฉพาะเมื่อมีการประกาศเป็นพารามิเตอร์ชนิดของวิธีการปิดล้อม ถ้ามันมาจากสมาชิกประเภทหรือพารามิเตอร์ประเภทของคุณลักษณะ / คลาสที่ล้อมรอบมันจะไม่คอมไพล์ตามที่คุณเห็นด้วยตัวคุณเอง
นี่คือเหตุผลที่ฉันบอกว่ามันไม่ใช่คำตอบที่สมบูรณ์ 100% - ฉันไม่สามารถชี้ไปยังสถานที่ที่เป็นรูปธรรม (เช่นข้อกำหนดอย่างเป็นทางการ) ซึ่งเอกสารนี้ถูกต้อง แหล่งที่มาของการจัดการ GADT ใน Scala นั้นมาลงที่บล็อกโพสต์สองสาม อัน ซึ่งยอดเยี่ยม แต่ถ้าคุณต้องการมากกว่านั้นคุณจะต้องขุดลงไปในคอมไพเลอร์โค้ดด้วยตัวเอง ฉันพยายามทำอย่างนั้นและฉันคิดว่าวิธีการนี้จะลงเอยแต่ถ้าคุณต้องการที่จะเจาะลึกลงไปจริงๆคุณอาจต้องการที่จะ ping คนที่มีประสบการณ์มากขึ้นด้วย codebase คอมไพเลอร์ Scala