2012-10-08 19 views
7

प्रतीकों के प्रकार class A[_] या def a[_](x: Any) में एक प्रकार का पैरामीटर है जिसे शरीर में संदर्भित नहीं किया जा सकता है, इस प्रकार मैं नहीं देखता कि यह कहां उपयोगी है और यह क्यों संकलित करता है। एक इस प्रकार पैरामीटर संदर्भ के लिए प्रयास करता है, एक त्रुटि फेंक दिया जाता है:'कक्षा ए [_]' के लिए उपयोगी क्या है?

scala> class A[_] { type X = _ } 
<console>:1: error: unbound wildcard type 
     class A[_] { type X = _ } 
          ^

scala> def a[_](x: Any) { type X = _ } 
<console>:1: error: unbound wildcard type 
     def a[_](x: Any) { type X = _ } 
           ^

कोई मुझे बता सकते हैं कि इस तरह के एक प्रकार स्काला में उपयोग के मामले है? सटीक होने के लिए, मेरा मतलब अस्तित्व प्रकार या उच्च प्रकार के प्रकारों के प्रकार पैरामीटर में नहीं है, केवल उन लिट [_] जो पूर्ण प्रकार पैरामीटर सूची बनाते हैं।

उत्तर

4

[संपादित करें:: "क्यों यह संकलित" case class Foo[_](i: Int) अभी भी अच्छी तरह से 2.9.2 पर दुर्घटनाओं] क्योंकि मैं जवाब मैं उम्मीद, मैं scala-language को यह लाया नहीं मिला।

मैं यहाँ पेस्ट लार्स Hupel से जवाब (हां, तो सभी क्रेडिट उसे लागू), जो ज्यादातर बताते हैं कि मैं क्या जानना चाहता था:

मैं यहाँ यह एक चाकू देने के लिए जा रहा हूँ। मुझे लगता है कि सुविधा सदस्यों के बारे में बात करते समय सुविधा का उपयोग साफ़ हो जाता है।

मान लें आप निम्नलिखित विशेषता लागू करने के लिए है:

trait Function { 
    type Out[In] 
    def apply[In](x: In): Out[In] 
} 

यह एक (सामान्य) समारोह जहां वापसी प्रकार इनपुट प्रकार पर निर्भर करता होगा। उदाहरण के लिए एक उदाहरण:

val someify = new Function { 
    type Out[In] = Option[In] def 
    apply[In](x: In) = Some(x) 
} 

someify(3) res0: Some[Int] = Some(3) 

अभी तक, बहुत अच्छा है। अब, आप निरंतर कार्य को कैसे परिभाषित करेंगे?

val const0 = new Function { 
    type Out[In] = Int 
    def apply[In](x: In) = 0 
} 

const0(3) res1: const0.Out[Int] = 0 

(प्रकार const0.Out[Int]Int के बराबर है, लेकिन यह कि जिस तरह से मुद्रित नहीं है।)

नोट कैसे प्रकार पैरामीटर In वास्तव में नहीं किया जाता है। तो, यहाँ कैसे आप इसे _ साथ लिख सकता है: प्रकार पैरामीटर जो वास्तव में करने के लिए भेजा नहीं किया जा सकता के लिए एक नाम के रूप में उस मामले में _ की

val const0 = new Function { 
    type Out[_] = Int 
    def apply[In](x: In) = 0 
} 

Think।यह प्रकार स्तर पर एक समारोह जो पैरामीटर के बारे में परवाह नहीं है के लिए एक है, बस मूल्य स्तर पर की तरह:

(_: Int) => 3 res4: Int => Int = <function1> 

छोड़कर ...

type Foo[_, _] = Int 
<console>:7: error: _ is already defined as type _ 
     type Foo[_, _] = Int 

की तुलना उस के साथ:

(_: Int, _: String) => 3 res6: (Int, String) => Int = <function2> 

तो, निष्कर्ष में:

type F[_] = ConstType // when you have to implement a type member def 
foo[_](...) // when you have to implement a generic method but don't 
      // actually refer to the type parameter (occurs very rarely) 

आपके द्वारा उल्लिखित मुख्य बात, class A[_], पूरी तरह से पर सममित है, सिवाय इसके कि कोई वास्तविक उपयोग केस नहीं है।

trait FlyingDog[F[_]] { def swoosh[A, B](f: A => B, a: F[A]): F[B] } 

अब मान आप अपने सादे वर्ष class A के लिए FlyingDog का एक उदाहरण बनाना चाहते:

इस पर विचार करें।

  1. घोषित class A[_] बजाय:

    दो समाधान कर रहे हैं। (ऐसा नहीं है।)

  2. एक प्रकार लैम्ब्डा का उपयोग करें:

    new FlyingDog[({ type λ[α] = A })#λ] 
    

या यहाँ तक कि

new FlyingDog[({ type λ[_] = A })#λ] 
1

यह उपयोगी है जब आप प्रकार पैरामीटर की देखभाल किए बिना parametrized प्रकारों के उदाहरणों से निपटते हैं।

trait Something[A] { 
    def stringify: String 
} 

class Foo extends Something[Bar] { 
    def stringify = "hop" 
} 

object App { 
    def useSomething(thing: Something[_]) :String = { 
    thing.stringify 
    } 
} 
+1

क्या तुम यहाँ मतलब है एक अस्तित्व प्रकार है, जो नहीं है मेरा मतलब था। – sschaef

2

स्काला में अंडरस्कोर, एक अस्तित्व प्रकार इंगित करता है एक अज्ञात प्रकार पैरामीटर है, जो दो मुख्य उपयोग है अर्थात्:

  • यह तरीकों जो प्रकार पैरामीटर के बारे में परवाह नहीं है के लिए प्रयोग किया जाता है
  • इसका उपयोग उन विधियों के लिए किया जाता है जहां आप व्यक्त करना चाहते हैं कि एक प्रकार पैरामीटर एक प्रकार का कन्स्ट्रक्टर है।

एक प्रकार का कन्स्ट्रक्टर मूल रूप से ऐसा कुछ है जिसे ठोस प्रकार बनाने के लिए एक प्रकार पैरामीटर की आवश्यकता होती है। उदाहरण के लिए आप निम्नलिखित हस्ताक्षर ले सकते हैं।

def strangeStuff[CC[_], B, A](b:B, f: B=>A): CC[A] 

यह एक समारोह है कि कुछ CC[_] के लिए, उदाहरण के एक List[_] के लिए, एक List[A] बनाता है एक बी और एक समारोह B=>A से शुरू है।

यह उपयोगी क्यों होगा? वैसे यह पता चला है कि यदि आप उस तंत्र का उपयोग implicits और typeclasses के साथ करते हैं, तो आप संकलक तर्क के लिए विज्ञापन-हाक पॉलीमोर्फिज्म कहलाते हैं। ठोस कार्यान्वयन के एक पदानुक्रम के साथ Container[_]:

उदाहरण के लिए कल्पना कीजिए कि आप कुछ उच्च kinded प्रकार है BeautifulContainer[_], BigContainer[_], SmallContainer[_]। एक कंटेनर का निर्माण करने के लिए आप की जरूरत है एक

trait ContainerBuilder[A[_]<:Container[_],B] { 

def build(b:B):A[B] 

} 

तो मूल रूप से एक ContainerBuilder कुछ है कि कंटेनर एक की एक विशिष्ट प्रकार के लिए [_] निर्माण कर सकते हैं एक ए [बी] एक बी का उपयोग कर

है कि होगा उपयोगी ? वैसे आप कल्पना कर सकते हैं कि आप एक समारोह की तरह निम्नलिखित कहीं और परिभाषित हो सकता है:

def myMethod(b:B)(implicit containerBuilder:ContainerBuilder[A[_],B]):A[B] = containerBuilder.build(b) 

और फिर अपने कोड में आप यह कर सकते हैं:

val b = new B() 
val bigContainer:BigContainer[B] = myMethod(b) 
val beautifulContainer:BeautifulContainer[B] = myMethod(b) 

वास्तव में, संकलक आवश्यक वापसी का उपयोग करेगा एक अंतर्निहित व्यक्ति को देखने के लिए myMethod का प्रकार जो आवश्यक प्रकार की बाधाओं को पूरा करता है और यदि कोई कंटेनरबिल्डर नहीं है जो निश्चित रूप से आवश्यक बाधाओं को पूरा करता है तो संकलन त्रुटि फेंक देगा।

+2

मेरा मतलब अस्तित्व प्रकार या उच्च प्रकार के प्रकारों के प्रकार के पैरामीटर के रूप में नहीं था, मेरा मतलब है कि एक प्रकार पैरामीटर मौजूद है लेकिन संदर्भित नहीं किया जा सकता है। – sschaef

+0

तो सही उत्तर पिछले एक – Edmondo1984

+0

है जो पिछले एक? वह हटा दिया गया है? – sschaef

4

मैं इसे यहाँ क्या मतलब हो सकता है के बारे में कुछ आकस्मिक विचारों था:

https://issues.scala-lang.org/browse/SI-5606

तुच्छ उपयोग के मामले के अलावा, एक नाम बनाने के लिए है क्योंकि मैं वास्तव में परवाह नहीं है संकलक पूछ (हालांकि शायद मैं 'll इसे बाद में नाम जब मैं वर्ग को लागू), यह एक अभी भी मुझे के रूप में उपयोगी हमलों: जहां एक प्रकार परम क्योंकि प्रकार निष्कर्ष में सुधार यह ज़रूरत से ज़्यादा कर हटा दिया गया है

एक और उपयोग है।

trait T[@deprecated("I'm free","2.11") _, B <: S[_]] 

फिर, परिकल्पित, एक लेकिन T[X, Y] के उपयोग नहीं T[_, Y] पर चेतावनी देने के कर सकते हैं।

हालांकि यह स्पष्ट नहीं है कि एनोटेशन पहले (मूल्य पैरामीटर-शैली) या बाद में (टाइप शैली पर एनोटेशन) आएगा या नहीं।

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