2011-04-04 17 views
10

के साथ संदर्भ सीमा शॉर्टकट उच्च प्रकार के प्रकार के साथ संदर्भ सीमा सिंटैक्स शॉर्टकट का उपयोग करना संभव है?उच्च प्रकार के प्रकार

trait One { def test[W : ClassManifest]: Unit } // first-order ok 
trait Two { def test[W[_]: ClassManifest]: Unit } // not possible?? 
trait Six { def test[W[_]](implicit m: ClassManifest[W[_]]): Unit } // hmm... 

उत्तर

11

हाँ, यह है, लेकिन अपने संदर्भ के लिए बाध्य प्रकार एक उच्च kinded प्रकार पैरामीटर (जो ClassManifest नहीं करता है) होना आवश्यक है।

scala> trait HKTypeClass[CC[_]] 
defined trait HKTypeClass 

scala> implicit def listHKTC = new HKTypeClass[List] {} 
listHKTC: java.lang.Object with HKTypeClass[List] 

scala> def frob[CC[_] : HKTypeClass] = implicitly[HKTypeClass[CC]] 
frob: [CC[_]](implicit evidence$1: HKTypeClass[CC])HKTypeClass[CC] 

scala> frob[List] 
res0: HKTypeClass[List] = [email protected] 

अद्यतन

यह एक प्रकार अन्य नाम का उपयोग करने के लिए एक उच्च kinded प्रकार पैरामीटर एक प्रथम क्रम संदर्भ बाध्य प्रकार से घिरा होने के लिए अनुमति देने के लिए संभव है। हम पहले-ऑर्डर प्रकार से उच्च-प्रकार का प्रकार बनाने के लिए टाइप-स्तरीय फ़ंक्शन के रूप में टाइप उपनाम का उपयोग करते हैं। ClassManifest के लिए यह इस तरह जा सकते हैं,

scala> type HKClassManifest[CC[_]] = ClassManifest[CC[_]] 
defined type alias HKClassManifest 

scala> def frob[CC[_] : HKClassManifest] = implicitly[HKClassManifest[CC]]   
test: [CC[_]](implicit evidence$1: HKClassManifest[CC])HKClassManifest[CC] 

scala> frob[List]              
res1: HKClassManifest[List] = scala.collection.immutable.List[Any] 

ध्यान दें कि प्रकार उर्फ ​​सीसी [_] के दाहिने हाथ की ओर एक प्रथम क्रम प्रकार है ... अंडरस्कोर यहाँ वाइल्डकार्ड है। नतीजतन इसे ClassManifest के लिए प्रकार तर्क के रूप में उपयोग किया जा सकता है।

अद्यतन

पूर्णता मैं नोट करना चाहिए कि प्रकार उर्फ ​​एक प्रकार लैम्ब्डा का उपयोग कर inlined किया जा सकता है के लिए, implicitly[ClassManifest[List[_]]]implicitly[ClassManifest[List[T] forSome {type T}]] के लिए कम है

scala> def frob[CC[_] : ({ type λ[X[_]] = ClassManifest[X[_]] })#λ] = implicitly[ClassManifest[CC[_]]]  
frob: [CC[_]](implicit evidence$1: scala.reflect.ClassManifest[CC[_]])scala.reflect.ClassManifest[CC[_]] 

scala> frob[List] 
res0: scala.reflect.ClassManifest[List[_]] = scala.collection.immutable.List[Any] 
+0

लेकिन 'क्लासमैनीफेस्ट' को इस बारे में जानने की आवश्यकता नहीं है कि इसके प्रकार पैरामीटर स्वयं अपेक्षाकृत अधिक दयालु है, जब तक कि वे उच्च प्रकार के बाध्य होते हैं (यहां तक ​​कि वाइल्डकार्ड के साथ), उदा। 'डीईएफ परीक्षण क्यों नहीं है [ए, बी [ए]: कक्षा प्रबंधन] {} की अनुमति है, हालांकि 'डीईएफ परीक्षण [ए, बी [ए]] (अंतर्निहित एम: कक्षा प्रबंधन [बी [ए]]) {}' है ? –

+0

क्लासमैनिफेस्ट को यह आवश्यक है कि इसका तर्क तर्क पहला ऑर्डर है जैसा कि आप देख सकते हैं कि क्या आप आरईपीएल में पूरी तरह से [क्लासमैनिफेस्ट [सूची]] का प्रयास करते हैं। –

+0

यही वह है जो मैं कह रहा हूं: इससे कोई फर्क नहीं पड़ता कि किस प्रकार का तर्क पहला आदेश या उच्च आदेश है, जब तक कि यह पहले क्रम में कम हो जाता है: 'निहित रूप से [कक्षा प्रबंधन [सूची [_]]] -> ठीक है ! तो मैं बस सोच रहा था कि मुझे इस मामले में संदर्भित संदर्भ के लिए शॉर्टकट क्यों नहीं मिल सकता है –

4

ध्यान दें कि।

यही कारण है कि यह काम करता है: ClassManifest एक उचित प्रकार तर्क की अपेक्षा करता है, और List[T] forSome {type T} एक उचित प्रकार है, लेकिन List एक प्रकार का कन्स्ट्रक्टर है।

:

दोनों ClassManifest[List[String]] और ClassManifest[List] काम बनाने के लिए हम संस्करणों कि अलग-अलग प्रकार के प्रकार पैरामीटर लेते हैं, कुछ की तरह साथ किसी भी तरह ClassManifest ओवरलोड आवश्यकता होगी (कृपया की "उचित" आदि परिभाषा देखने के लिए What is a higher kinded type in Scala? देखें)

class ClassManifest[T] // proper type 
class ClassManifest[T[_]] // type constructor with one type parameter 
class ClassManifest[T[_, _]] // type constructor with two type parameters 
// ... ad nauseam 

(एक शैक्षणिक टिप्पणी, "उचित" यह करने के लिए रास्ते पर, प्रकार से अधिक सार संक्षेप अनुमति देने के लिए किया जाएगा:

class ClassManifest[T : K][K] 

    implicitly[ClassManifest[String]] // --> compiler infers ClassManifest[String][*] 
    implicitly[ClassManifest[List]] // --> compiler infers ClassManifest[List][* -> *] 

)

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