2012-02-08 15 views
7

में प्रकार मैं एक उच्च kinded प्रकारबाधा उच्च Kinded स्काला

SuperMap[Key[_],Value[_]]`. 

अब मान लीजिए कि मैं कुछ और भी विशिष्ट है कि यह आवश्यक था कि Key के लिए प्रकार पैरामीटर Value के लिए कि मेल खाना चाहिए था है कहो; कि कुछ की तरह है, यह है:

SuperDuperMap[T, Key[T], Value[T]] 

इसके अलावा लगता है कि मैं सिर्फ नहीं करना चाहता था किसी भी T, लेकिन एक बहुत ही विशेष एक जहाँ T <: OtherT

SuperDuperPooperMap[T <: OtherT, Key[T], Value[T]] 

इस स्काला में किया जा सकता है? क्या यह आम तौर पर एक बुरा विचार है? क्या ऐसा करने का एक समकक्ष तरीका है जो पढ़ने/लिखने/उपयोग करना आसान है?

उत्तर

11

आपका घोषणा पहले से ही काम करता है। जिस तरह से आप यह लिखा है, तथापि, स्केला अगर आप की तरह

scala> class Foo[T <: OtherT, Key[T], Value[T]] 
defined class Foo 

scala> new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]] 
<console>:13: error: Key[SpecialOtherT] takes no type parameters, expected: one 
       new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]] 

कुछ क्योंकि दोनों Key और Value के प्रकार पहले से ही अपने पूर्व घोषणा द्वारा दिया जाता है जारी शिकायत करेंगे। इसलिए यह

scala> new Foo[SpecialOtherT, Key, Value] 
res20: Foo[SpecialOtherT,Key,Value] = [email protected] 

जो संभवतः आप नहीं चाहते हैं। आप इसे कुछ हद तक जब Foo के साथ काम है कि सभी अनावश्यक जानकारी के लिए ज़रूरत से ज़्यादा है इस

scala> class Foo[T <: OtherT, K <: Key[T], V <: Value[T]] 
defined class Foo 

scala> new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]] 
res21: Foo[SpecialOtherT,Key[SpecialOtherT],Value[SpecialOtherT]] = [email protected] 

लब्बोलुआब पर लगता है कि यह कर सकता है, के बाद से Key और Value के प्रकार T पर पूरी तरह निर्भर करते हैं।तो क्यों इतने की तरह एक आंतरिक प्रकार घोषणा का उपयोग नहीं:

class Foo[T <: OtherT] { 
    type K = Key[T] 
    type V = Value[T] 
} 

तो फिर तुम वर्ग के भीतर से और V प्रकार K के लिए उपयोग किया था लेकिन हर बार एक नई उत्तर बनाना लिखने की आवश्यकता नहीं होगी:

scala> new Foo[SpecialOtherT] 
res23: Foo[SpecialOtherT] = [email protected] 

scala> new Foo[Int] 
<console>:11: error: ... 
+0

धन्यवाद! बहुत सूचनाप्रद। मेरा एकमात्र जवाब "तो एक आंतरिक प्रकार की घोषणा का उपयोग क्यों न करें" यह है कि मैं उन प्रकारों को के और वी के लिए तत्कालता पर अनुमानित करना चाहता हूं। – duckworthd

+0

मुझे यकीन नहीं है कि मैं समझता हूं क्योंकि वास्तव में अनुमान अनुमानित है। आपके उपयोग-मामले के आधार पर, आप अभी भी "बाहरी" से प्रकार का उपयोग कर सकते हैं, उदा। 'कक्षा फू [टी]; कक्षा बार [टी] {प्रकार वी = फू [टी]}; def do कुछ [टी] (बी: बार [टी]) (अंतर्निहित एमएफ: प्रकट [बार [टी] #Wee]) {कंसोल println mf} ', और फिर 'कुछ कुछ (नया बार [डबल])'। सहमत है, यह एक गंदा उदाहरण है। – fotNelton

3

क्या यह स्कैला में किया जा सकता है?

आपका क्या मतलब है? तुमने अभी किया!

क्या यह आम तौर पर एक बुरा विचार है?

ऐसा क्यों होगा? वास्तव में यह एक अच्छा विचार है! यह उच्च प्रकार के प्रकार के लिए हैं।

क्या ऐसा करने का एक समकक्ष तरीका है जो पढ़ने/लिखने/उपयोग करना आसान है?

पढ़ना - मुझे बहुत अच्छी तरह से पढ़ता है।

लेखन - लिखना/परीक्षण/संकलन एक बार, हर जगह उपयोग करें।

का उपयोग करना - कंपाइलर "हर जगह" प्रकारों का पुन: निर्माण (अनुमानित) करेगा। माना जाता है, यानी आप T के साथ-साथ Key और Value के प्रकार सीमित कर रहे हैं के रूप में

+0

जबकि मेरा कोड संकलित करता है, इसे तत्काल नहीं किया जा सकता है: एक्स – duckworthd

2

आप शायद कुछ भी प्रकार उपनाम की एक जोड़ी से अधिक जटिल की जरूरत नहीं है,

type SuperDuperMap[T, Key[_], Value[_]] = SuperMap[Key, Value] 

type SuperDuperPooperMap[T <: OtherT, Key[_], Value[_]] = SuperMap[Key, Value] 

नमूना आरईपीएल सत्र,

scala> new SuperDuperMap[Int, Option, List] {} 
res0: java.lang.Object with SuperDuperMap[Int,Option,List] = ... 

scala> new SuperDuperPooperMap[OtherT, Option, List] {} 
res1: java.lang.Object with SuperDuperPooperMap[OtherT,Option,List] = ...