2009-07-26 10 views
8

मान लीजिए मेरे पास दो कक्षाएं हैं, Input और Output, जिन्हें एक दूसरे से कनेक्ट करने के लिए डिज़ाइन किया गया है। Output कुछ प्रकार के मान उत्पन्न करता है, और Input उन्हें खपत करता है।स्कैला इस उदाहरण में टाइप पैरामीटर का अनुमान क्यों नहीं लगा सकता है?

class Input[T] { 
    var output: Option[Output[_ <: T]] = None 
} 
class Output[T] { 
    var input: Option[Input[_ >: T]] = None 
} 

अगर एक Input और Output जोड़ी मूल्य का एक ही तरह पर जब तक Input प्रकार पैरामीटर Output प्रकार पैरामीटर के महाप्रकार है काम नहीं करते यह ठीक है। ध्यान दें कि दोनों वर्गों में प्रकार पैरामीटर invariant है; वास्तविक संस्करणों में इसका उपयोग दोनों सह-और contravariant पदों में किया जाता है।

val out = new Output[String] 
val in = new Input[AnyRef] 
connect(out, in) 

:

def connect[T](output: Output[T], input: Input[_ >: T]) = { 
    output.input = Some(input) 
    input.output = Some(output) 
} 

अगर मैं नीचे के रूप में इस विधि कहते हैं, मैं एक प्रकार त्रुटि मिलती है:

मैं कहीं और एक connect विधि है जो एक Input/Output जोड़ी के बीच एक कड़ी सेट है त्रुटि है:

test.scala:17: error: type mismatch; 
found : Output[String] 
required: Output[AnyRef] 
    connect(out, in) 
     ^

मैं कर सकता हूँ टाइप पैरामीटर लिखकर इसे हल करें (इस मामले में, मैं connect[String] लिखूंगा, लेकिन मुझे लगता है कि संकलक मेरे लिए इसे समझने में सक्षम होना चाहिए। मैं connect विधि कैसे बदल सकता हूं ताकि प्रकार पैरामीटर स्वचालित रूप से अनुमानित हो?


संपादित करें: अभी के लिए, मैं connectOutput की एक विधि है, तो यह प्रकार पैरामीटर स्वचालित रूप से हो जाता है बना दिया है। इसमें अतिरिक्त लाभ भी है कि मैं इंफिक्स नोटेशन out connect in का उपयोग कर सकता हूं, लेकिन डिज़ाइन थोड़ा अजीब लगता है।

मुझे अभी भी दिलचस्पी है कि संकलक इस व्यवहार को क्यों प्रदर्शित करता है। मुझे लगता है कि यह प्रकार पैरामीटर का अनुमान लगाने में सक्षम होना चाहिए। क्या यह वास्तव में निर्दिष्ट के रूप में काम कर रहा है?

+0

क्या आपका मतलब है "उसी प्रकार के मूल्य पर * काम न करें" –

+0

क्या आपने स्कैला मेलिंग सूची में प्रश्न पूछने का प्रयास किया है? – GClaramunt

उत्तर

6

आप कभी-कभी अच्छे परिणाम देगा यदि आप कई पैरामीटर सूचियों का उपयोग:

def connect[T](output: Output[T])(input: Input[_ >: T]) = { 
    output.input = Some(input) 
    input.output = Some(output) 
} 

connect(out)(in) 

... और वास्तव में इस मामले में, यह काम करता है।

+3

क्या आप विस्तार कर सकते हैं यह क्यों है? * "कभी-कभी बेहतर परिणाम प्राप्त होते हैं" * बहुत दृढ़ संकल्प नहीं करता है! –

+6

अफसोस की बात है कि टाइप इनफ्रेंसर का नमूना नहीं है, और कभी-कभी निर्धारक भी नहीं होता है। –

0

मैं पूरी तरह से गलत हो सकता हूं, लेकिन मुझे लगता है कि समस्या तब होती है जब आप इनपुट और आउटपुट को जोड़ते हैं: इनपुट में आउटपुट आउटपुट टी के उप-प्रकार तक सीमित है, लेकिन आउटपुट में एक सुपरर्ट टाइप तक सीमित इनपुट है टी, एकमात्र प्रकार जो दोनों स्थितियों को पूरा कर सकता है टी है।

Input[T] -> Output[ _ <: T ] 
Output[Q] -> Input[ _ >: Q ] 

जब आप निर्गम (साथ क्यू की जगह _ <: टी) के साथ इनपुट बनाने आपको मिलेगा:

Input[T]->Input[ _ >: [_ <: T] ] 

एक ही रूप में

इनपुट [टी] -> इनपुट [_ <: टी <: _]

इसलिए प्रकार मेल नहीं खाता

+0

मेरे उदाहरण में, स्ट्रिंग और AnyRef मेरी बाधाओं को पूरा करते हैं। आउटपुट स्ट्रिंग्स का उत्पादन करता है और एक इनपुट की आवश्यकता होती है जो स्ट्रिंग के कुछ सुपरटेप का उपभोग करती है। इनपुट AnyRefs का उपभोग करता है और एक आउटपुट की आवश्यकता होती है जो AnyRef के कुछ उप प्रकार का उत्पादन करती है। चूंकि स्ट्रिंग AnyRef का एक उप प्रकार है, बाधाएं संतुष्ट हैं। –

+0

समस्या यह है कि कनेक्ट के लिए बिल्कुल एक उचित प्रकार पैरामीटर है, और यह आउटपुट का प्रकार पैरामीटर है। जब मैं इसे स्पष्ट रूप से निर्दिष्ट करता हूं, तो यह ठीक काम करता है। यदि मैं नहीं करता, तो यह इनपुट के प्रकार पैरामीटर का उपयोग करने का प्रयास करता है, और मुझे आउटपुट तर्क पर एक प्रकार त्रुटि मिलती है। –

+0

क्षमा करें, मैंने कनेक्ट के हस्ताक्षर में इनपुट [_>: टी] को गलत तरीके से पढ़ा [टी] ( – GClaramunt

0

असल में स्कैला प्रकार इनफरेंस अब के लिए "रिकर्सन" संभाल नहीं सकता है। तो यदि तर्क के प्रकार को केवल अन्य तर्क के साथ कॉलोकेशन में शामिल किया जा सकता है तो स्केल अनुमान में विफल रहता है। लेकिन यदि आप अलग-अलग तर्क सूची का उपयोग करते हैं तो स्कैला f(a)(b)(c,d) सूची द्वारा प्रकारों की सूची का अनुमान लगाएगा, इसलिए यह वास्तव में बेहतर काम करता है।

पीएस यह अतिसंवेदनशील है, लेकिन आपको कुछ सुराग मिल सकता है।

संबंधित मुद्दे