2011-01-06 13 views
5

निम्नलिखित स्केला कोड मान्य प्रतीत हो रहा है:स्कैला के प्रकार प्रणाली में बग?

class A[X] 
class C[M[X] <: A[X]] 

class Main 

new C[A] 

मैं संकलक की उम्मीद ग्रुप ए पर प्रकार निष्कर्ष प्रदर्शन करने के लिए, लेकिन उसके बाद मैंने कोशिश की है:

new C[A[Int]] 

मैं निम्नलिखित त्रुटि संदेश मिला :

(fragment of Main.scala):11: error: this.A[Int] takes no type parameters, expected: one 
println(new C[A[Int]]) 

उत्तर

2

आप C के लिए एक प्रकार पैरामीटर के रूप में X घोषित नहीं किया था। निम्न का प्रयास करें:

class C[X, M[X] <: A[X]] 
+0

यह नौकरी भी नहीं करेगा। समस्या यह है कि सी एक प्रकार के पैरामीटर के साथ एक प्रकार की अपेक्षा करता है। जब आप नई सी [ए] आज़माते हैं तो यह काम करने जा रहा है, क्योंकि ए एक प्रकार का तर्क लेता है। – tim

+0

यह काम नहीं करेगा - सी अब दो प्रकार के मानकों की अपेक्षा करता है। – gpampara

6

इस वाक्यविन्यास को आजमाएं।

class C[M <: A[_]] 

इसका मतलब यह है कि सी एक वर्ग है कि एक प्रकार पैरामीटर है, जो एक के एक उपवर्ग हो सकता है और एक प्रकार पैरामीटर लेता है चाहिए लेता है।

15

चलिए देखते हैं कि सादे अंग्रेजी में इसका क्या अर्थ है।

class A[X] 

का अर्थ है: एक वर्ग बनें जो एक प्रकार का पैरामीटर लेता है।

class C[M[X] <: A[X]] 

का अर्थ है: सी एक वर्ग है कि एक प्रकार पैरामीटर है, जो एक वर्ग है कि एक प्रकार पैरामीटर लेता है और, पैरामिट्रीकृत होना चाहिए लेता हो, वर्ग एक ही प्रकार के साथ एक पैरामिट्रीकृत का एक उपवर्ग है।

जब आप

new C[A] 

बारे में तुम कह रहे हो: पैरामीटर के रूप में एक साथ सी का एक उदाहरण बना सकते हैं। क्या उपर्युक्त मानदंडों का पालन करता है? हां, यह एक वर्ग है जो एक प्रकार का पैरामीटर लेता है, और पैरामीटरकृत यह पैरामीटरकृत स्वयं का उप-वर्ग है।

हालांकि, जब तुम

new C[A[Int]] 

प्रकार पैरामीटर आप सी, एक [इंट] देने के लिए कोशिश कर रहे हैं लिखते हैं, मापदंड के अनुरूप नहीं है: एक [इंट] किसी भी प्रकार के पैरामीटर नहीं ले करता है, जो संकलक कृपया आपको बताता है। (और यह ए [एक्स] का उप-वर्ग नहीं है।)

+1

यह सही उत्तर है; एकमात्र चीज जिसे मैं जोड़ूं (वेब ​​खोजों में सहायता के लिए) यह है कि यह एक उच्च प्रकार के प्रकार का एक उदाहरण है, जहां सी को टाइप पैरामीटर को दयालु * -> * के रूप में संदर्भित किया जाता है। एक [Int] इसके विपरीत बस दयालु * है। –

+0

क्या आपका मतलब 'सी' के बजाय' ए' था? 'ए [इंट] 'का प्रकार' * 'है, लेकिन ए' * -> * 'होना चाहिए, नहीं? फिर 'सी'' (* -> *) -> * 'होना चाहिए? – Emre

0

आप अपनी कक्षा को एक प्रकार का पैरामीटर लेने के लिए नहीं चाहते हैं, तो आप इसे दो नहीं ले पाएंगे! दो संभव समाधान:

class A[X] { 
    type T = X 
} 
class C[M <: A[_]] { 
    //use M#T if you want the type T was parameterized with. 
} 

या, आप कर सकते हैं:

class A[X] 
class C[T, M[A] <: A[A]] { 
    //when you want the type, write M[T], not M. 
} 

हालांकि, आप शायद चाहते हैं यह है:

class A[X] 
class C[M <: A[_]] 
+0

इसे आसान बनाने के लिए, यह जावा में समतुल्य है: कक्षा ए {...} // सभी के लिए। कक्षा सी <एम एक > {...} // पहले विस्तारित करता है। यद्यपि सही नहीं है। // दूसरा संभव नहीं है। – Anonymous

1

यह सब समझाया है here, "आम पर ध्यान केंद्रित संकट "खंड क्योंकि यह काफी टीएलटीआर है।

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