2012-05-15 19 views
23

मेरा मानना ​​है कि एक (कम से कम, वस्तुओं के लिए) सहप्रसरण परिभाषित कर सकते हैं 'के रूप में एक संकरा (उप) के मान का उपयोग करने के लिए कुछ व्यापक (सुपर) के मान के स्थान पर टाइप टाइप क्षमता', और कहा कि contravariance सटीक है इसके विपरीत।फ़ंक्शन [-A1, ..., + B] पैरामीटर के रूप में किसी भी सुपरटेप को अनुमति देने के बारे में क्यों नहीं है?

जाहिर है, स्कैला फ़ंक्शंस फंक्शंस के उदाहरण हैं [-A1, ..., + B] contravariant पैरामीटर प्रकार A1, आदि और कॉन्वर्सेंट रिटर्न प्रकार, बी के लिए। हालांकि यह कार्य पर subtyping के लिए आसान है, उपरोक्त परिभाषा का मतलब है कि मैं पैरामीटर के रूप में किसी भी supertypes पारित कर सकते हैं?

कृपया सलाह दें कि मुझे कहां गलत है।

उत्तर

56

सहप्रसरण और contravariance वर्ग नहीं मापदंडों के गुणों के गुण हैं। (वे गुण है कि मानकों पर निर्भर हैं, लेकिन वे वर्ग के बारे में बयान करते हैं।)

तो, Function1[-A,+B] मतलब यह है कि एक समारोह कि A की सुपर-क्लास लेता मूल कार्य का एक उपवर्ग के रूप में देखा जा सकता है।

के व्यवहार में यह देखते हैं:

def needsB(f: B => Unit, b: B) = f(b) 

आप printB पास कर सकता है:

class A 
class B extends A 
val printB: B => Unit = { b => println("Blah blah") } 
val printA: A => Unit = { a => println("Blah blah blah") } 

अब आप एक समारोह को पता है कि मुद्रित करने के लिए कैसे एक B की आवश्यकता होती है लगता है। लेकिन printA में पास हो सकता है, क्योंकि यह भी जानता है कि B एस (और अधिक!) कैसे प्रिंट करें, जैसे कि A => UnitB => Unit का उप-वर्ग था। यह वास्तव में contravariance मतलब है। इसका मतलब यह नहीं है कि आप Option[Double]printB में पास कर सकते हैं और संकलन-समय त्रुटि के अलावा कुछ भी प्राप्त कर सकते हैं!

(सहप्रसरण अन्य मामला है:। M[B] <: M[A] अगर B <: A)

+0

धन्यवाद, यह बहुत स्पष्ट था। (पुनः) परिभाषित करने का प्रयास: 'सह/अनुबंध-भिन्नता गुणों के बीच उप प्रकार के संबंध को निर्देशित करने वाली गुण हैं, जो उनके घटक प्रकारों के बीच समान संबंध की प्रकृति के अधीन हैं।' सार, मुझे पता है, लेकिन मैं उदाहरणों से रहित परिभाषा को पसंद करता हूं (हालांकि आपका बहुत उपयोगी था)। – bjt38

+0

एए के लिए धन्यवाद, क्या आप समझ सकते हैं कि फंक्शन 1 में + बी क्यों है [-A, + B] – liango

+0

@liango - उदाहरण के द्वारा एक्सप्लोरेशन: यदि आप 'स्ट्रिंग' वापस करते हैं तो आप निश्चित रूप से 'ऑब्जेक्ट' वापस कर देते हैं, इसलिए '। .. => स्ट्रिंग' '= = ऑब्जेक्ट' का उप-वर्ग होना चाहिए। यही है 'बी' संकेत करता है। –

4

यहां काम पर दो अलग-अलग विचार हैं। एक उप-टाइपिंग का उपयोग कर रहा है ताकि किसी फ़ंक्शन को अधिक विशिष्ट तर्क पारित किए जा सकें (जिसे सबसमशन कहा जाता है)। दूसरी बात यह है कि कार्यों पर खुद को उप-जांच कैसे करें।

प्रकार की जाँच एक समारोह के तर्क के लिए, आप केवल जांच करने के लिए है कि दिए गए तर्कों के घोषित तर्क प्रकारों के उपप्रकार होते हैं। नतीजा भी घोषित प्रकार का उप प्रकार होना चाहिए। यह वह जगह है जहां आप वास्तव में उप प्रकार की जांच करते हैं।

विपरीत/मानकों & परिणाम केवल कारक के लिए जब आप हैं कि कोई समारोह प्रकार एक और समारोह प्रकार का एक उप-प्रकार है जाँच करना चाहते हैं में सह विचरण। तो यदि पैरामीटर में Function[A1, ... ,B] टाइप किया गया है, तो तर्क को फ़ंक्शन प्रकार Function[C1, ..., D] होना चाहिए जहां A1 <: C1 ... और D <: B है।

यह तर्क स्कैला के लिए विशिष्ट नहीं है और उप-टाइपिंग के साथ अन्य स्थैतिक-टाइप की गई भाषाओं पर लागू होता है।

-1

covariant व्यापक (सुपर) से संकरा (उप) में परिवर्तित करने का मतलब है।उदाहरण के लिए, हमारे पास दो वर्ग हैं: एक जानवर (सुपर) है और दूसरा बिल्ली है तो कॉन्वेंटेंट का उपयोग करके, हम पशु को बिल्ली में बदल सकते हैं।

कॉन्ट्रा-वेरिएंट सिर्फ कॉन्वेंटेंट के विपरीत है, जिसका मतलब जानवर को बिल्ली है।

Invariant का अर्थ यह परिवर्तित करने में असमर्थ है।

18

यह प्रश्न पुराना है, लेकिन मुझे लगता है कि एक स्पष्ट स्पष्टीकरण Liskov प्रतिस्थापन सिद्धांत का आह्वान करना है: सुपरक्लास के बारे में जो कुछ भी सच है, उसके सभी उप-वर्गों के बारे में सच होना चाहिए। आपको एक सबफू सब कुछ करने में सक्षम होना चाहिए जो आप फू के साथ कर सकते हैं, और शायद अधिक।

मान लीजिए कि हमारे पास कैलिको < है: बिल्ली <: पशु, और हुस्की <: कुत्ता <: पशु। आइए Function[Cat, Dog] देखें। इसके बारे में क्या बयान सही हैं? वहाँ दो हैं:

(1) आप किसी भी कैट (बिल्ली की इसलिए किसी भी उपवर्ग) में पारित कर सकते हैं

(2) आप दिए गए मान पर कोई कुत्ता विधि कॉल कर सकते हैं

तो Function[Calico, Dog] <: Function[Cat, Dog] मेकअप भावना करता है ? नहीं, सुपरक्लास के सत्य जो बयान उपclass, अर्थात् कथन (1) के बारे में सच नहीं हैं। आप किसी भी बिल्ली में एक समारोह में गुजर नहीं सकते हैं जो केवल कैलिको बिल्लियों को लेता है।

लेकिन Function[Animal, Dog] <: Function[Cat, Dog] समझ में आता है? हां, सुपरक्लास के बारे में सभी बयान सबक्लास के बारे में सच हैं। मैं अभी भी किसी भी बिल्ली में गुजर सकता हूं - असल में मैं उससे भी ज्यादा कर सकता हूं, मैं किसी भी पशु में गुजर सकता हूं - और मैं लौटे हुए मूल्य पर सभी कुत्ते के तरीकों को बुला सकता हूं।

तो A <: BFunction[B, _] <: Function[A, _]

अब तात्पर्य Function[Cat, Husky] <: Function[Cat, Dog] कोई मतलब है? हां, सुपरक्लास के बारे में सभी बयान उपclass के सच हैं; मैं अभी भी एक बिल्ली में गुजर सकता हूं, और मैं अभी भी लौटे मूल्य पर सभी कुत्ते के तरीकों को कॉल कर सकता हूं - असल में मैं उससे भी अधिक कर सकता हूं, मैं लौटे हुए मूल्य पर सभी हुस्की विधियों को कॉल कर सकता हूं।

लेकिन Function[Cat, Animal] <: Function[Cat, Dog] समझ में आता है? नहीं, सुपरक्लास के सत्य जो बयान उपclass, अर्थात् कथन (2) के बारे में सच नहीं हैं। मैं कुत्ते पर उपलब्ध सभी विधियों को वापस लौटाया नहीं जा सकता, केवल पशु पर उपलब्ध हैं।

तो Function[Animal, Husky] के साथ मैं Function[Cat, Dog] के साथ जो कुछ भी कर सकता हूं वह कर सकता हूं: मैं किसी भी बिल्ली में जा सकता हूं, और मैं लौटे हुए मूल्य पर सभी कुत्ते विधियों को कॉल कर सकता हूं। और मैं और भी कर सकता हूं: मैं अन्य जानवरों में जा सकता हूं, और मैं कुत्ते पर उपलब्ध विधियों को बुला सकता हूं जो कुत्ते पर उपलब्ध नहीं हैं। तो यह समझ में आता है: Function[Animal, Husky] <: Function[Cat, Dog]। पहले प्रकार पैरामीटर को सुपरक्लास के साथ प्रतिस्थापित किया जा सकता है, दूसरा सबक्लास के साथ।

+0

मैं उन उदाहरणों के साथ प्रोग्रामेटिक रूप से कैसे जांच सकता हूं? –