2015-12-06 5 views
5

मैं head और tail के प्रकार पर scala में एक list के विभिन्न खण्डों पर pattern match चाहते हैं:एक स्कैला सूची के पैटर्न और सिर के पूंछ प्रकार कैसे पैटर्न?

class Solution07 extends FlatSpec with ShouldMatchers { 
    "plain recursive flatten" should "flatten a list" in { 
    val list1 = List(List(1, 1), 2, List(3, List(5, 8))) 
    val list1Flattened = List(1, 1, 2, 3, 5, 8) 

    flattenRecur(list1) should be (list1Flattened) 
    } 

    def flattenRecur(ls: List[Any]): List[Int] = ls match { 
    case (head: Int) :: (tail: List[Any]) => head :: flattenRecur(tail) 
    case (head: List[Int]) :: (tail: List[Any]) => head.head :: flattenRecur(head.tail :: tail) 
    case (head: List[Any]) :: (tail: List[Any]) => flattenRecur(head) :: flattenRecur(tail) // non-variable type... on this line. 
    } 
} 

मैं:

Error:(18, 17) non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure case (head: List[Int]) :: (tail: List[Any]) => head.head :: flattenRecur(head.tail :: tail) ^

मैं क्या याद आ रही है? सूची के लिए head और tail के प्रकार पर पैटर्न मिलान करना मेरे लिए कैसे संभव है?

+1

'केस (सिर: सूची [Int]) :: (पूंछ: सूची [कोई भी]) =>' 'केस के साथ (हेडहेड: Int) :: (हेडटेल: सूची [कोई भी]) :: :: (पूंछ: सूची [कोई भी]) => 'यह आपको टाइप एरर – ayvango

+0

से लड़ने की अनुमति देगा, यह मुद्दा लाइन के मामले के लिए है (सिर: सूची [कोई भी]) :: (पूंछ: सूची [कोई भी])' आपने उल्लेख किया है अलग लाइन, क्या वह लाइन भी मदद करने के लिए माना जाता है ??? – Jas

+1

तीसरे विकल्प दूसरे के साथ संघर्ष। तो आप या तो दूसरी पसंद या तीसरी पसंद समायोजित कर सकते हैं। चूंकि तीसरी पसंद अधिक सामान्य है, इसलिए दूसरा और विशिष्ट – ayvango

उत्तर

6

मैं मानता हूँ कि HList साथ @Andreas समाधान समस्या को हल करने के लिए एक अच्छी मिसाल है, लेकिन मैं अभी भी समझ में नहीं आता इस के साथ समस्या क्या:

def flatten(ls: List[_]): List[Int] = ls match { 
    case Nil => Nil 
    case (a: Int) :: tail => a :: flatten(tail) 
    case (a: List[_]) :: tail => flatten(a) ::: flatten(tail) 
    case _ :: tail => flatten(tail) 
    } 

तब:

println(flatten(List(List("one",9,8),3,"str",4,List(true,77,3.2)))) // List(9, 8, 3, 4, 77) 

मुझे आपके कार्य में टाइप एरर के साथ कोई समस्या नहीं दिख रही है, क्योंकि आपको वास्तव में मिटाए गए प्रकारों का परीक्षण करने की आवश्यकता नहीं है। मैंने जानबूझकर मेरे उदाहरण में सभी मिटाए गए प्रकारों को छोड़ दिया है - इसे दिखाने के लिए। टाइप एरर सूची के तत्वों की प्रकार की जानकारी को साफ़ नहीं करता है, यह केवल मेरे सामान्य मामले में Any या _ है जो सूची जेनेरिक की प्रकार की जानकारी को साफ़ करता है - इसलिए आपको इसकी आवश्यकता नहीं है। अगर मैं कभी याद नहीं कर रहा हूं, तो आपके उदाहरण में प्रकारों को मिटाया नहीं जाता है, क्योंकि आपके पास लगभग हर जगह Any है।

+1

आप इस अवलोकन के साथ सही हैं :) क्या मुझे जवाब अनुकूलित करना चाहिए? –

+1

शायद, मैं सिर्फ टाइप एरर के बारे में बयान हटा दूंगा। मुझे लगता है कि 'एचएलआईस्ट' का उपयोग करने का प्रस्ताव एक अच्छा विकल्प है, लेकिन मुझे नहीं लगता कि यह एकमात्र विकल्प है - आप इसके बिना आसानी से रह सकते हैं। – Archeg

+1

और मुझे शायद यह उल्लेख करना चाहिए कि मैंने अभी तक आकारहीन उपयोग नहीं किया है, इसलिए मैं यह निर्णय लेने में अधिकार नहीं रखता कि यह अच्छा दृष्टिकोण है – Archeg

1

मिराज टाइप करने के कारण आप प्रत्येक तत्व का निरीक्षण कर सकते हैं।

def flattenRecur(ls: List[Any]): List[Int] = ls match { 
    case head :: tail if (head.isInstanceOf[Int]) 
        => head.asInstanceOf[Int] :: flattenRecur(tail) 
    case head :: tail if (head.isInstanceOf[List[Any]]) 
        => flattenRecur(head.asInstanceOf[List[Any]]) ++ 
         flattenRecur(tail) 
    case _ :: tail => flattenRecur(tail) 
    case _ => Nil 
} 

कौन सा दिखाई देता है काम करने के लिए:

scala> flattenRecur(List(List("one",9,8),3,"str",4,List(true,77,3.2))) 
res8: List[Int] = List(9, 8, 3, 4, 77) 

लेकिन अंगूठे का एक सामान्य नियम के रूप में, Any परहेज आम तौर पर प्रयास के लायक है।

+0

प्रकारों को पकड़ लेगा, मैं चाहता हूं कि मैं 'किसी भी' से बच सकूं लेकिन जब मैंने 'वैल सूची 1 = सूची (सूची (1, 1), 2, सूची (3, सूची (5, 8) परिभाषित की)) तो इसका प्रकार है पहले से ही 'सूची [कोई भी]' इसके लिए एक अलग प्रकार के लिए किया जा सकता है जो मुझे 'टाइप एरर' से आगे बचाएगा? – Jas

1

आप वस्तु प्रणाली द्वारा दिए गए प्रतिबंध से मारा जाता है:

केवल आम माता-पिता List[Int] और Int के लिए Any

तो कारण है कि अनुमान प्रणाली केवल सुरक्षित रूप से मान सकते हैं कि आप Any लौट सकता है। समाधान प्रस्तावित @jwvh करने योग्य है लेकिन रनटाइम अपवादों का संभावित खतरा है।

आप एक typesafe तरह से समस्या का समाधान चाहते हैं एक विकल्प निराकार पुस्तकालय https://github.com/milessabin/shapeless की HList उपयोग करने के लिए हो सकता है: https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#heterogenous-lists

+1

क्या आप नीचे दिए गए उत्तर में अपना उदाहरण देख सकते हैं? मुझे नहीं लगता (2) सच है - अनुक्रम अंदर मौजूद तत्वों के प्रकारों के बारे में जानता है। यह केवल उस 'टी' के बारे में नहीं जानता है जिसे कार्य के लिए जरूरी नहीं है। मैं सहमत हूं कि 'एचएलआईस्ट' महान हैं और वे इसे हल करने के संभावित विकल्पों में से एक हैं, लेकिन यह एकमात्र विकल्प नहीं है – Archeg

+0

आपके विस्तारित उत्तर के लिए यह पूरी तरह से सही है। प्रकार मिटा आपको प्रभावित नहीं करता है। –

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