2010-09-28 10 views
9

निम्न कोड पर विचार करें:अंतर्निहित पैरामीटर संकल्प

object foo { 

    trait Bar[Q[_]] 

    implicit object OptionBar extends Bar[Option] 

    def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) =() 

    def main(args: Array[String]) { 
     test(Some(42): Option[Int]) //??? 
    } 
} 

यह काम करता है, लेकिन मैं कुछ (42) के रूप में विकल्प [इंट] है, और अंतर्निहित वस्तु OptionBar नहीं होगा टाइप करने की आवश्यकता हल किया गया (क्योंकि इसके बजाय एक बार [कुछ] की उम्मीद है)। क्या स्पष्ट टाइपिंग से बचने का कोई तरीका है, ताकि मैं परीक्षण में ऑब्जेक्टबार ऑब्जेक्ट प्राप्त कर सकूं, भले ही मैं कुछ या किसी के साथ परीक्षण खिलाऊं?

[स्पष्टीकरण]

  • मैं यहाँ विकल्प का इस्तेमाल किया सिर्फ उदाहरण के रूप में, यह भी है कि अगर मैं एक अमूर्त वर्ग आदि के लिए एक Bar है
  • समाधान भी काम करना चाहिए जब अन्य, असंबंधित बार्स हैं काम करना चाहिए दायरे में, कहते हैं कि implicit object listBar extends Bar[list]

[अपडेट]

ऐसा लगता है कि बार की पैरामीटर contravariant बनाने टी करता है उन्होंने चाल:

object foo { 

    trait Bar[-Q[_]] //<--------------- 

    implicit object OptionBar extends Bar[Option] 
    implicit object ListBar extends Bar[List] 

    def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) =() 

    def main(args:Array[String]) { 
    test(Some(42)) 
    } 
} 

लेकिन निश्चित रूप से इस बार में संभावनाओं की एक गंभीर सीमा है, इसलिए मैं अभी भी एक बेहतर जवाब के लिए उम्मीद है।

+1

गंभीर सीमा का उल्लंघन क्यों होता है? इसका उपयोग किए बिना, बार बार invariant है। यदि आप बार को उच्च प्रकार के प्रकारों के खिलाफ टाइप-क्लास के रूप में उपयोग करने का प्रयास कर रहे हैं जो कि मेरे दिमाग में विपरीत लगता है। यह निश्चित रूप से तब तक है जब तक आप उप-वर्गों का अलग-अलग व्यवहार नहीं करना चाहते। हालांकि, उस मामले में, आपके पास अभी भी अन्य चालें हैं, जैसे कि निहित संकल्प "प्राथमिकताओं" – jsuereth

+0

@ जोश: 'विशेषता बार [क्यू [_]] {डीफ़ शून्य [टी]: क्यू [टी]} जैसे कुछ पर विचार करें, कोई भी नहीं बचा रहा है और मेरे उदाहरणों में नील। लेकिन अगर मैं क्यू को contravariant के रूप में परिभाषित करता हूं, तो मेरे पास बार में ऐसी कोई विधि नहीं हो सकती है। जब आप इसे हल करने के बारे में जानते हैं, तो कृपया मुझे बताएं ... – Landei

+1

इसके अलावा, एक समान रूप से contravariant प्रकार वर्ग के लिए, जैसे 'समान [टी]', निहित खोज 'समान [पशु]' बराबर [कुत्ते] ': http://www.scala-lang.org/node/4626। विरासत और प्रकार के वर्ग एक साथ जाल करने के लिए वास्तव में मुश्किल हैं। – retronym

उत्तर

7

यह सभी मामलों में काम करने के लिए नहीं जा रहा है, लेकिन जैसा कि कहा गया है, आप यह कोशिश कर सकते हैं:

def test[T, C[_], D <: C[T]](c: D)(implicit bar: Bar[C]) =() 
: हालांकि यह एक ही बात को व्यक्त करता है

object foo { 
    trait Bar[Q[_]] 

    implicit object OptionBar extends Bar[Option] 

    def test[T, C[_], D](c: D)(implicit bar: Bar[C], ev: D <:< C[T]) =() 

    def main(args: Array[String]) { 
    test(Some(42)) //??? 
    } 
} 

दिलचस्प है, इस अनुमान नहीं करता है,

<:< के बारे में अधिक जानकारी के लिए देखें:

+0

यह काम करता है, हालांकि यदि आप उस दायरे में बार के लिए एक और निहित जोड़ते हैं, तो कहें कि 'निहित वस्तु सूचीबार बार [सूची] को बढ़ाता है, आपको एक "संदिग्ध अंतर्निहित मूल्य" त्रुटि मिलती है। – Landei

+0

मैं इस जवाब को बक्षीस देता हूं, क्योंकि यह एक अच्छी तकनीक दिखाता है और प्रारंभिक प्रश्न हल करता है, जिसे सटीक रूप से पर्याप्त रूप से तैयार नहीं किया गया था। हालांकि मैं अभी भी "अस्पष्ट अंतर्निहित मूल्यों" समस्या को हल करने के संकेत देने के लिए सराहना करता हूं। – Landei

+0

ठीक है, स्केल के तीन साल और कई संस्करण बाद में, ऐसा लगता है कि कोई जवाब मौजूद नहीं है। (मुझे एक ही चुनौती का सामना करना पड़ रहा है।) – Tim

5

क्योंकि Some(42) है कि Option[Int] तुलना में एक अधिक विशिष्ट प्रकार है। यह Some[Int] है। नीचे वैकल्पिक कोडिंग देखें:

object foo { 

    trait Bar[Q[_]] 

    implicit object OptionBar extends Bar[Option] 

    def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) =() 

    def main(args: Array[String]) { 
     test(Option(42)) 
    } 
} 
+1

मैं वास्तव में 'Option.apply' का उपयोग करके वकालत नहीं करता जब तक कि इसे शून्य जांच को एन्कोड करने के लिए उपयोग न किया जाए। संयोग से, स्कालाज़ के साथ, मैं '42.some' या' 42.pure [Option] 'लिखूंगा, जिनमें से दोनों' विकल्प [Int] 'के रूप में टाइप करेंगे। – retronym

+0

@ संक्षिप्त नाम - आप 'Option.apply' का उपयोग करके वकील क्यों नहीं करते? –

+1

मैं इसका उपयोग करता हूं जब मेरे पास संभावित रूप से शून्य संदर्भ होता है जो 'कुछ' या 'कोई नहीं' में परिवर्तित करना चाहता है। मैं 'कुछ (एक्स): विकल्प [ए]' पढ़ सकता हूं और कारण यह है कि 'x'' की उत्पत्ति के बिना मेरे पास 'कुछ' होगा। यदि तर्क एक शाब्दिक है, जैसा कि इस उदाहरण में, यह ठीक है हालांकि। – retronym

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