साइटी पेटन-जोन्स के कागजात में नट-किरकिरा विवरण शामिल हैं, हालांकि उन्हें समझने के लिए तकनीकी विशेषज्ञता का एक अच्छा सौदा होता है। यदि आप हास्केल प्रकार अनुमान कैसे काम करते हैं, इस पर एक पेपर पढ़ना चाहते हैं, तो आपको सामान्यीकृत बीजगणितीय डेटा प्रकार (जीएडीटी) के बारे में पढ़ना चाहिए, जो कई अन्य विशेषताओं के साथ अस्तित्वहीन प्रकारों को जोड़ती है। मैं http://research.microsoft.com/en-us/people/simonpj/ पर कागजात की सूची पर, "जीएडीटी के लिए पूर्ण और अनुमानित प्रकार अनुमान" का सुझाव देता हूं।
मौजूदा मात्रा वास्तव में सार्वभौमिक मात्रा की तरह बहुत काम करती है। दोनों के बीच समानता को हाइलाइट करने के लिए यहां एक उदाहरण दिया गया है। फ़ंक्शन useExis
बेकार है, लेकिन यह अभी भी वैध कोड है।
data Univ a = Univ a
data Exis = forall a. Exis a
toUniv :: a -> Univ a
toUniv = Univ
toExis :: a -> Exis
toExis = Exis
useUniv :: (a -> b) -> Univ a -> b
useUniv f (Univ x) = f x
useExis :: (forall a. a -> b) -> Exis -> b
useExis f (Exis x) = f x
सबसे पहले, ध्यान दें कि toUniv
और toExis
लगभग एक ही हैं। उनके पास एक नि: शुल्क प्रकार पैरामीटर a
है क्योंकि दोनों डेटा कन्स्ट्रक्टर पॉलीमोर्फिक हैं। लेकिन a
toUniv
के रिटर्न प्रकार में दिखाई देता है, लेकिन यह toExis
के रिटर्न प्रकार में दिखाई नहीं देता है। जब डेटा प्रकार कन्स्ट्रक्टर का उपयोग करने से आपको प्रकार की त्रुटियों की बात आती है, तो अस्तित्व और सार्वभौमिक प्रकारों के बीच कोई बड़ा अंतर नहीं होता है।
दूसरा, रैंक -2 प्रकार forall a. a -> b
useExis
में नोट करें। टाइप अनुमान में यह बड़ा अंतर है। पैटर्न मिलान (Exis x)
से लिया गया अस्तित्व प्रकार फ़ंक्शन के शरीर को पारित एक अतिरिक्त, छुपा प्रकार चर की तरह कार्य करता है, और इसे अन्य प्रकारों के साथ एकीकृत नहीं किया जाना चाहिए। यह स्पष्ट करने के लिए, पिछले दो कार्यों की कुछ गलत घोषणाएं दी गई हैं जहां हम उन प्रकारों को एकजुट करने का प्रयास करते हैं जिन्हें एकीकृत नहीं किया जाना चाहिए। दोनों मामलों में, हम x
के प्रकार को एक असंबंधित प्रकार चर के साथ एकीकृत करने के लिए मजबूर करते हैं। useUniv
में, प्रकार परिवर्तक फ़ंक्शन प्रकार का हिस्सा है। useExis
में, यह डेटा संरचना से मौजूद अस्तित्व का प्रकार है।
useUniv' :: forall a b c. (c -> b) -> Univ a -> b
useUniv' f (Univ x) = f x -- Error, can't unify 'a' with 'c'
-- Variable 'a' is there in the function type
useExis' :: forall b c. (c -> b) -> Exis -> b
useExis' f (Exis x) = f x -- Error, can't unify 'a' with 'c'.
-- Variable 'a' comes from the pattern "Exis x",
-- via the existential in "data Exis = forall a. Exis a".