คลาสชนิดพอดีกับรุ่นนี้ได้อย่างไร
คำตอบสั้น ๆ คือ: พวกเขาทำไม่ได้
เมื่อใดก็ตามที่คุณแนะนำ coercions ประเภทชั้นเรียนหรือกลไกอื่น ๆ สำหรับความแตกต่าง Ad-hoc ให้เป็นภาษาที่ปัญหาการออกแบบหลักที่คุณต้องเผชิญคือการเชื่อมโยงกัน
โดยทั่วไปคุณจะต้องตรวจสอบให้แน่ใจว่าความละเอียดของคลาสนั้นกำหนดขึ้นเพื่อให้โปรแกรมที่พิมพ์ได้ดีมีการตีความเพียงครั้งเดียว ตัวอย่างเช่นหากคุณให้หลายอินสแตนซ์สำหรับประเภทเดียวกันในขอบเขตเดียวกันคุณอาจเขียนโปรแกรมที่ไม่ชัดเจนเช่นนี้:
class Blah a where
blah : a -> String
instance Blah T where
blah _ = "Hello"
instance Blah T where
blah _ = "Goodbye"
v :: T = ...
main :: IO ()
main = print (blah v) -- does this print "Hello" or "Goodbye"?
ทั้งนี้ขึ้นอยู่กับทางเลือกของอินสแตนซ์คอมไพเลอร์ที่ทำให้ที่blah v
อาจเท่ากับอย่างใดอย่างหนึ่งหรือ"Hello"
"Goodbye"
ดังนั้นความหมายของโปรแกรมจะไม่ถูกกำหนดโดยไวยากรณ์ของโปรแกรม แต่อาจได้รับอิทธิพลจากการเลือกโดยพลการของคอมไพเลอร์
การแก้ปัญหาของ Haskell สำหรับปัญหานี้คือต้องการให้แต่ละประเภทมีตัวอย่างได้ไม่เกินหนึ่งตัวอย่างสำหรับแต่ละประเภท เพื่อให้แน่ใจว่าสิ่งนี้จะอนุญาตการประกาศอินสแตนซ์ที่ระดับบนสุดเท่านั้นและทำให้การประกาศทั้งหมดมองเห็นได้ทั่วโลก ด้วยวิธีนี้คอมไพเลอร์สามารถส่งสัญญาณข้อผิดพลาดได้เสมอหากมีการประกาศอินสแตนซ์ที่คลุมเครือ
อย่างไรก็ตามการประกาศทั่วโลกทำให้มองเห็นการแบ่งองค์ประกอบของความหมาย สิ่งที่คุณสามารถทำได้เพื่อกู้คืนคือการให้ความหมายอย่างละเอียดสำหรับภาษาโปรแกรม - นั่นคือคุณสามารถแสดงวิธีการแปลโปรแกรม Haskell เป็นภาษาที่มีความประพฤติดีขึ้น
สิ่งนี้จะช่วยให้คุณสามารถรวบรวมประเภทของพิมพ์ดีดได้เช่นกัน - โดยปกติจะเรียกว่า "การแปลหลักฐาน" หรือ "การแปลงผ่านพจนานุกรม" ในแวดวง Haskell และเป็นหนึ่งในช่วงแรกของคอมไพเลอร์ Haskell ส่วนใหญ่
Typeclasses เป็นตัวอย่างที่ดีของการออกแบบภาษาโปรแกรมที่แตกต่างจากทฤษฎีชนิดบริสุทธิ์ Typeclasses เป็นคุณสมบัติทางภาษาที่ยอดเยี่ยม แต่พวกมันค่อนข้างประพฤติตัวไม่ดีในมุมมองเชิงทฤษฎีที่พิสูจน์ได้ (นี่คือสาเหตุที่ Agda ไม่มีคลาสพิมพ์เลยและเหตุใด Coq จึงทำให้พวกเขาเป็นส่วนหนึ่งของโครงสร้างพื้นฐานการอนุมานแบบแก้ปัญหา)