मेरे एक दोस्त ने पिछले हफ्ते एक स्पष्ट रूप से निर्दोष स्कैला भाषा प्रश्न पेश किया था कि मेरे पास कोई अच्छा जवाब नहीं था: क्या कुछ सामान्य टाइपक्लास से संबंधित चीजों का संग्रह घोषित करने का एक आसान तरीका है । बेशक स्कैला में "टाइपक्लास" की कोई प्रथम श्रेणी की धारणा नहीं है, इसलिए हमें इसके बारे में लक्षणों और संदर्भ सीमाओं (यानी implicits) के संदर्भ में सोचना होगा।अपरिवर्तनीय प्रकार बनाम सादे पुराने उपप्रकार
Concretely, कुछ विशेषता T[_]
एक typeclass का प्रतिनिधित्व करने दिया, और प्रकार A
, B
और C
, T[A]
गुंजाइश, T[B]
और T[C]
में इसी implicits साथ, हम एक List[T[a] forAll { type a }]
की तरह कुछ है, जो में हम A
के उदाहरण फेंक कर सकते हैं की घोषणा करना चाहते हैं , B
और C
अपमान के साथ। यह निश्चित रूप से स्कैला में मौजूद नहीं है; एक question last year अधिक गहराई में इस पर चर्चा करता है।
प्राकृतिक अनुवर्ती प्रश्न यह है कि "हास्केल यह कैसे करता है?" खैर, विशेष रूप से जीएचसी "Boxy Types" पेपर में वर्णित impredicative polymorphism नामक एक प्रकार का सिस्टम एक्सटेंशन है। संक्षेप में, एक टाइपक्लास T
दिया गया है, कोई कानूनी रूप से एक सूची [forall a. T a => a]
बना सकता है। इस फ़ॉर्म की घोषणा को देखते हुए, कंपाइलर कुछ शब्दकोश-गुजरने वाले जादू करता है जो हमें रनटाइम पर सूची में प्रत्येक मान के प्रकारों के अनुरूप टाइपक्लास उदाहरणों को बनाए रखने देता है।
बात यह है कि, "शब्दकोश-गुजरने वाला जादू" बहुत कुछ "vtables" जैसा लगता है। स्काला जैसी ऑब्जेक्ट-ओरिएंटेड भाषा में, सबटाइपिंग "बॉक्सी प्रकार" दृष्टिकोण की तुलना में एक बहुत ही सरल, प्राकृतिक तंत्र है। यदि हमारे A
, B
और C
सभी विशेषता T
का विस्तार करते हैं, तो हम केवल List[T]
घोषित कर सकते हैं और खुश रह सकते हैं। इसी प्रकार, जैसा कि माइल्स नीचे एक टिप्पणी में नोट करता है, यदि वे सभी T1
, T2
और T3
गुणों का विस्तार करते हैं तो मैं List[T1 with T2 with T3]
का उपयोग अपमानजनक हास्केल [forall a. (T1 a, T2 a, T3 a) => a]
के बराबर के रूप में कर सकता हूं।
हालांकि, मुख्य, जाने-माने typeclasses की तुलना में subtyping साथ नुकसान तंग युग्मन है: मेरे A
, B
और C
प्रकार उनकी T
व्यवहार में पकाया करना होगा मान लेते हैं यह एक बड़ी dealbreaker है, और मैं कर सकते हैं। टी उप प्रकार का उपयोग करें। तो स्काला में बीच मैदान दलाल^एच^एच^एच^एच^Himplicit रूपांतरण है: दिए गए कुछ A => T
, B => T
और निहित दायरे में C => T
, मैं फिर से काफी खुशी से एक List[T]
मेरी A
, B
और C
मूल्यों के साथ पॉप्युलेट कर सकते हैं ...
... जब तक हम List[T1 with T2 with T3]
नहीं चाहते हैं। उस बिंदु पर, भले ही हमारे पास A => T1
, A => T2
और A => T3
अंतर्निहित रूपांतरण हैं, हम सूची में A
नहीं डाल सकते हैं। हम अपने अंतर्निहित रूपांतरणों को शाब्दिक रूप से A => T1 with T2 with T3
प्रदान करने के लिए पुन: स्थापित कर सकते हैं, लेकिन मैंने कभी भी ऐसा नहीं देखा है, और ऐसा लगता है कि यह तंग युग्मन का एक और रूप है।
ठीक है, तो मेरे सवाल का अंत है, मुझे लगता है, कुछ सवाल का एक संयोजन है कि पहले यहां पूछा गया: "why avoid subtyping?" और "advantages of subtyping over typeclasses" ... वहाँ कुछ एकीकृत सिद्धांत का कहना है कि impredicative बहुरूपता और उप-प्रकार बहुरूपता एक और एक ही कर रहे हैं ? क्या किसी भी तरह से गुप्त प्यार-दोनों के गुप्त प्यार हैं? और क्या कोई स्केल में कई सीमाओं (ऊपर के अंतिम उदाहरण के रूप में) व्यक्त करने के लिए एक अच्छा, साफ पैटर्न व्यक्त कर सकता है?
यह प्रासंगिक हो सकता है: http://stackoverflow.com/questions/7213676/forall-in-scala – missingfaktor
@ missingfaktor यह निश्चित रूप से है, इसलिए मैंने इसे लिंक किया है! – mergeconflict
आह, क्षमा करें, पहले पढ़ने में याद किया! – missingfaktor