2012-11-22 14 views
13

कहते हैं कि हम निम्न दो लक्षण है:स्काला दृश्य आवेदन पहेली

val bar = new Bar {} 
val stuff = List(1, 2, 3) 

अब मैं काम करने के लिए निम्न उम्मीद थी:

bar howMany stuff 

लेकिन यह नहीं है:

दृश्य तीन स्थितियों में लागू होते हैं:

scala> bar howMany stuff 
<console>:13: error: type mismatch; 
found : List[Int] 
required: List[A] 
       bar howMany stuff 
         ^

तो हम the spec करने के लिए जाना है, जो इस में क्या कहना है (बोल्ड अक्षरों में जोर मेरा है) ।

  1. [यहाँ प्रासंगिक नहीं है।]

  2. एक चयन में उन्हेंसाथ ई प्रकार टी, की अगर चयनकर्ता मीटरके एक सदस्य को निरूपित नहीं है टी। इस मामले में, एक दृश्य v खोजा गया है जो पर लागू होता है और जिसके परिणामस्वरूप मीटर नामक सदस्य होता है। अंतर्निहित पैरामीटर के मामले में खोज की आय, जहां अंतर्निहित दायरा टी में से एक है। यदि ऐसा कोई दृश्य मिलता है, तो चयन ई.एम को v (e) .m में परिवर्तित किया गया है।

  3. एक चयन में उन्हें (args)साथ ई प्रकार टी, की अगर चयनकर्ता मीटरके कुछ सदस्य (सदस्यों) टी को दर्शाता है, लेकिन इन सदस्यों में से कोई भी के लिए लागू है तर्क तर्क। इस मामले में एक दृश्य के वी जो करने के लिए लागू है खोजा जाता है और जिसका परिणाम एक विधि मीटर जो आर्ग के लिए लागू होता है। खोज के मामले में अंतर्निहित पैरामीटर के मामले में होती है, जहां अंतर्निहित दायरा टी में से एक है। यदि इस तरह का एक दृश्य मिलता है, तो चयन ई.एम को v (e) .m (args) में परिवर्तित किया गया है।

तो हम निम्नलिखित की कोशिश, यह सोच कर यह काम करने के लिए भी बेतुका होना चाहिए:

trait Foo[A] { def howMany(xs: List[A]) = xs.size } 
trait Bar { def howMany = throw new Exception("I don't do anything!") } 

implicit def bar2foo[A](bar: Bar) = new Foo[A] {} 

val bar = new Bar {} 
val stuff = List(1, 2, 3) 

लेकिन यह (दोनों 2.9.2 और 2.10.0-RC2 पर, कम से कम) करता है :

scala> bar howMany stuff 
res0: Int = 3 

यह वास्तव में कुछ अजीब व्यवहार की ओर जाता है this problem के लिए this workaround में उदाहरण के लिए के रूप में।

मैं तीन (निकट से संबंधित) प्रश्न हैं:

  1. वहाँ एक सीधा रास्ता नहीं है (यानी, एक है कि उचित नाम के साथ नकली विधियां जोड़ने शामिल नहीं है) दृश्य मूल में सही ढंग से लागू करने के लिए उपरोक्त मामला?
  2. क्या कोई इस व्यवहार के लिए जिम्मेदार नमूना पढ़ सकता है?
  3. मान लीजिए यह इरादा व्यवहार है, क्या यह कोई समझ में आता है?

मैं इस मुद्दे की पिछली चर्चाओं के किसी भी लिंक की भी सराहना करता हूं- मुझे Google के साथ बहुत भाग्य नहीं मिला है।

उत्तर

1

हर किसी के संदर्भ के लिए, यह केवल एक बग हो सकता है।

<console>:13: error: type mismatch; 
found : List[Int] 
required: List[A] 

सूची [एक] है नहीं एक असली प्रकार है - यह सूची अपने स्वयं के प्रकार पैरामीटर के लिए आवेदन किया है: जिस तरह से आप जानते हैं कि त्रुटि संदेश है। यह एक ऐसा प्रकार नहीं है जिसकी आवश्यकता हो सकती है क्योंकि यह एक प्रकार नहीं है जिसे व्यक्त किया जा सकता है।

[संपादित करें - यह बहुत जल्दी है, जो जानता है कि मैं किस बारे में बात कर रहा हूं। उपरोक्त को अनदेखा करें, लेकिन आप अभी भी लिंक का अनुसरण कर सकते हैं।]

इसके लिए प्रासंगिक टिकट https://issues.scala-lang.org/browse/SI-6472 है।

0

इस के साथ अपने फू की जगह:

trait Foo[_] { def howMany(xs: List[_]) = xs.size }

यह काम करता है, जो भी मेरे लिए काफी एक बहुत अधिक समझ में आता है, क्योंकि आपके absolutly ए में कोई दिलचस्पी नहीं

+0

यह उस विशेष सरलीकृत मामले में काम करता है, लेकिन आम तौर पर मुझे प्रश्न में जुड़े स्कालज़ समस्या के लिए कामकाज में 'ए' की परवाह है। –

0

आपका अंतर्निहित रूपांतरण हो रहा है ठीक वही कर रहे हैं जो आपने इसे करने के लिए कहा था।

implicit def bar2foo[A](bar: Bar) = new Foo[A] {} 

एक बार को एक नए Foo[A] ऑब्जेक्ट में परिवर्तित करता है। तो बदले में

scala> bar howMany stuff 
<console>:13: error: type mismatch; 
found : List[Int] 
required: List[A] 
       bar howMany stuff 

यह 'ए' प्रकार की तलाश में है।

इस काम को जिस तरह से आप चाहते हैं (मुझे लगता है), इस विशेषता पर विचार को परिभाषित करने के बजाय आप इसे फ़ंक्शन पर कर सकते हैं।

trait Foo { def howMany[A](xs: List[A]) = xs.size } 
trait Bar 
implicit def bar2foo[A](bar: Bar) = new Foo{} 
val bar = new Bar {} 
val stuff = List(1, 2, 3) 

तो यह आपको इच्छित परिणाम देना चाहिए।

scala> bar howMany stuff 
res0: Int = 3 

या आप अंतर्निहित समारोह

trait Foo[A] { def howMany(xs: List[A]) = xs.size } 
trait Bar 

implicit def bar2foo[A](bar: Bar) = new Foo[Int] {} 

val bar = new Bar {} 
val stuff = List(1, 2, 3) 

निजी तौर पर पर समारोह क्लीनर है मैं इसे परिभाषित करने लगता है पर दृश्य निर्धारित कर सकते हैं।

+0

जो मैं चाहता हूं वह "स्पष्ट" व्यवहार है- यानी, 'फू' के 'ए' पैरामीटर के लिए तर्क (ओं) के आधार पर अनुमानित किया जाना चाहिए कि 'कितनी' है। यह स्पष्ट रूप से संभव है, क्योंकि मैं इसे 'पूरी तरह से मनमाने ढंग से परिभाषित) नकली' कितनी 'विधि' बार 'जोड़कर कर सकता हूं। –

1

यह एक बग की तरह लगता है तो मेरे जवाब हैं: एक simliar बग स्काला संकलक के खिलाफ और न मिलने पर, एक नया बग https://issues.scala-lang.org/

  • कि कल्पना का हिस्सा नहीं करता है 'की रिपोर्ट सूचना के लिए

    1. खोज टी के रूप में यह प्रकार निष्कर्ष के बारे में बात नहीं कर रहा है इस मामले में बात करने के
    2. मेरे लिए

    पुनश्च किसी भी मतलब नहीं है लग रहे हैं। 2.8.1 में बार में डमी विधि जोड़ने का आपका कामकाज इसे संकलित नहीं करता है।

  • 0

    यह है, जबकि बदसूरत, काम करने के लिए प्रकट होता है:

    (bar: Foo[Int]) howMany stuff