2013-04-19 9 views
32

मैं समझने की कोशिश कर रहा हूं कि कैसे फोल्ड और फोल्ड लेफ्ट और संबंधित कम करें और कम करें। क्यों foldfoldLeft के रूप में काम नहीं किया मैं अपने उदाहरणस्कैला: फोल्ड बनाम foldLeft

scala> val r = List((ArrayBuffer(1, 2, 3, 4),10)) 
scala> r.foldLeft(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) 

scala> res28: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(5) 

scala> r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) 
<console>:11: error: value _1 is not a member of Serializable with Equals 
       r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) 

के रूप में गुना और foldLeft इस्तेमाल किया? Serializable with Equals क्या है? मैं समझता हूं कि पैरामीटर जेनेरिक प्रकारों के मामले में फोल्ड और फोल्ड लाइफ्ट में थोड़ा अलग API हस्ताक्षर है। कृपया सलाह दें। धन्यवाद।

+3

संभावित डुप्लिकेट [फोल्ड और फोल्ड लेफ्ट या फ़ोल्ड राइट के बीच अंतर?] (Http://stackoverflow.com/q/6253978) –

+0

स्कैला का कौन सा संस्करण? –

+0

मेरा स्कैला संस्करण 2.10.1 – thlim

उत्तर

54

विधि fold (मूल रूप से समांतर गणना के लिए जोड़ा गया) foldLeft से कम शक्तिशाली है जिस पर इसे लागू किया जा सकता है। इसके हस्ताक्षर है:

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 

इसका मतलब यह है कि जिस प्रकार से अधिक तह किया जाता है संग्रह तत्व प्रकार का एक महाप्रकार हो गया है।

def foldLeft[B](z: B)(op: (B, A) => B): B 

कारण यह है कि fold समानांतर में लागू किया जा सकता है, जबकि foldLeft नहीं कर सकता। यह केवल *Left भाग के कारण नहीं है जिसका अर्थ है कि foldLeft अनुक्रमिक रूप से बाएं से दाएं ओर जाता है, लेकिन यह भी क्योंकि ऑपरेटर op समांतर में गणना किए गए परिणामों को गठबंधन नहीं कर सकता है - यह केवल तत्व प्रकार के साथ समेकन प्रकार B को गठबंधन करने के तरीके को परिभाषित करता है, लेकिन B के दो समेकन को कैसे जोड़ना है। बदले में fold विधि इसे परिभाषित करती है, क्योंकि समेकन प्रकार A1 तत्व प्रकार A का सुपरटेप होना चाहिए, जो A1 >: A है। यह सुपरटेप रिश्ते एक ही समय में एकत्रीकरण और तत्वों पर तब्दील हो जाता है, और एकत्रीकरण को जोड़ता है - दोनों एक ऑपरेटर के साथ।

लेकिन, समेकन और तत्व प्रकार के बीच यह सुपरटेप संबंध यह भी है कि आपके उदाहरण में एकत्रीकरण प्रकार A1(ArrayBuffer[Int], Int) का सुपरटेप होना चाहिए। चूंकि आपके समेकन का शून्य तत्व प्रकार ArrayBuffer[Int] प्रकार है, इसलिए समेकन प्रकार इन दोनों के सुपरटेप होने का अनुमान लगाया गया है - और यह Serializable with Equals है, जो टुपल और सरणी बफर का केवल कम से कम ऊपरी सीमा है।

सामान्य रूप से, यदि आप मनमानी प्रकारों (जो क्रम से बाहर किया जाता है) के लिए समानांतर फोल्डिंग की अनुमति देना चाहते हैं तो आपको विधि aggregate विधि का उपयोग करना होगा, जिसमें यह परिभाषित करने की आवश्यकता है कि दो समेकन कैसे संयुक्त होते हैं। आपके मामले में:

r.aggregate(ArrayBuffer(1, 2, 4, 5))({ (x, y) => x -- y._1 }, (x, y) => x intersect y) 

Btw, reduce/reduceLeft के साथ अपने उदाहरण लिखने का प्रयास करें - तत्व प्रकार और एकत्रीकरण प्रकार इन दोनों तरीकों है कि बीच महाप्रकार संबंधों की वजह से है, तो आप पाएंगे कि यह एक करने के लिए सुराग आपके द्वारा वर्णित एक जैसी त्रुटि।

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