2012-10-24 4 views
7

है, मैं स्कैला के लिए नया हूं और मुझे टाइप सिस्टम के बारे में कोई सवाल है।स्कैला प्रकार चेकर एक सूची में फ़्लैटन को कॉल करने से रोकने के लिए कैसे जानता है जो पहले से ही फ्लैट

फ़्लैटन विधि नेस्टेड संग्रहों पर काम करती है, इसलिए यदि मेरे पास सूची की सूची है तो यह इसे एक सूची में फट जाएगा। लेकिन यह पहले से ही एक संग्रह पर flatten कॉल करने के लिए समझ में नहीं आता है। और निश्चित रूप से पर्याप्त स्कैला प्रकार चेकर इसे एक त्रुटि के रूप में ध्वजांकित करेगा।

List(List(1,2,3),List(4,5,6)).flatten // produces List(1,2,3,4,5,6) 
List(1,2,3,4).flatten // type error 

मैं समझता हूं कि यह किसी भी तरह से फ़्लैटन करने के लिए एक अंतर्निहित पैरामीटर पर निर्भर करता है। लेकिन मुझे नहीं पता कि निहित मूल्य कहां से आता है और ऑब्जेक्ट फ़्लैटन के प्रकार पर जोर देने के लिए इसका उपयोग कैसे किया जाता है। साथ ही, List.flatten के लिए scaladocs में अंतर्निहित पैरामीटर क्यों दिखाई नहीं देता है?

उत्तर

4

यह कैसे काम करता समझने के लिए, हम समतल के प्रकार के हस्ताक्षर पर एक नजर है की जरूरत है:

def flatten[B](implicit asTraversable: (A) ⇒ GenTraversableOnce[B]): List[B] 

A सूची के तत्व प्रकार है और B प्रत्येक तत्व के तत्वों के प्रकार है। काम करने के लिए फ़्लैटन के लिए, तत्व प्रकारों से GenTraversableOnce[B] पर एक निहित रूपांतरण होना चाहिए। संग्रह के लिए यह केवल मामला है या यदि आप अपना खुद का निहित रूपांतरण लागू करते हैं। उदाहरण के लिए, आप जोड़े के लिए एक निर्धारित कर सकते हैं:

implicit def pairToList[A](p:(A,A)) = List(p._1, p._2) 

List(1->2,2->3).flatten //compiles! List(1,2,2,3) 
+0

रूपांतरण को अंतर्निहित नहीं होना चाहिए, यह भी काम करता है: सूची (1-> 2,3-> 4) .flatten (पी => सूची (पी ._1, पी ._2)) –

+1

निश्चित रूप से, कोई अंतर्निहित पैरामीटर स्पष्ट रूप से भी पारित किया जा सकता है। –

1

चाल एक अंतर्निहित गवाह है कि सुनिश्चित करता है कि सूची में तत्वों traversable हो रहा है। यहाँ (थोड़ा सरलीकृत) flatten के हस्ताक्षर GenericTraversableTemplate से लिया है:

def flatten[B](implicit asTraversable: A => TraversableOnce[B]) 
       : GenTraversable[B] = 

आपके मामले में, गवाह प्रकार Int के तत्वों के लिए नहीं पाया जा सकता है, और flatten के आह्वान इसलिए संकलक द्वारा अस्वीकार कर दिया गया है।


आप अपने उदाहरण संकलन बनाना चाहते थे, तो आप निम्न अंतर्निहित परिभाषा इस्तेमाल कर सकते हैं:

implicit def singleToList[A](a: A) = List(a) 

(एक अतिरिक्त नोट के रूप: मैं इस तरह के एक काफी खतरनाक रूप में निहित, विचार करूँगा यह है के बाद से प्रयोज्यता बहुत सामान्य है, जिसके परिणामस्वरूप अप्रिय आश्चर्य हो सकता है क्योंकि संकलक बिना किसी जानकारी के आपको विभिन्न स्थानों पर आमंत्रण इंजेक्शन दे सकता है।)

+0

क्या मानक पुस्तकालय में कहीं है जहां सूची से ट्रैवर्सबल ओन में कनवर्ट करने के लिए एक निहित घोषित किया गया है? या क्या यह स्वचालित रूप से अस्तित्व में है क्योंकि सूची ट्रैवर्सएबल एक उपप्रकार है? –

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