2011-03-25 12 views
9

को intuitively निम्नलिखित काम करना चाहिए करने के लिए:रूपांतरण सेट और वापस Seq

case class I(i: Int) 
val s = Seq(I(1),I(2),I(3)) 
s.sortBy(_.i)    // works 
s.toSeq.sortBy(_.i)  // works 
s.toSet.toSeq.sortBy(_.i) // doesn´t work 

क्यों नहीं करता यह अपेक्षा के अनुरूप व्यवहार?

उत्तर

15

यह covariant और अपरिवर्तनीय संग्रह मिश्रण का एक जटिल प्रभाव है:

लेकिन निम्न दोनों चाल है। सेट invariant है: Set[A]। लेकिन सेक कॉन्वर्सेंट है: Seq[+A]। अब, कल्पना करें कि आप अपने सेक में toSet विधि चाहते हैं। आप toSet: Set[A] आज़मा सकते हैं। लेकिन यह काम नहीं करेगा, क्योंकि AB का उप-वर्ग है, तो Seq[A] को Seq[B] के उप-वर्ग के रूप में माना जाना चाहिए। हालांकि, Seq[A]Set[A] लौटने पर जोर देता है जो Seq[B] का उप-वर्ग नहीं है। तो हमारा टाइप टूटा हुआ है।

, तो दूसरी ओर, हम निर्दिष्ट toSeq[B >: A]: Set[B] तो सब कुछ ठीक है: यदि हम वादा करता हूँ कि हम किसी भी सुपर क्लास लौट सकते हैं, तो Seq[A]Set[B] के साथ-साथ Set[C] लौट सकते हैं जहां CB की एक सुपर क्लास है। Seq[B] ने Set[B] या कुछ Set[C] वापस करने का वादा किया है, इसलिए हम स्पष्ट हैं: Seq[A] पर विधि Seq[B] पर विधि कर सकते हैं सब कुछ कर सकते हैं। - अर्थात् तय करते हैं कि BI है और उसके अनुसार कार्य और C टाइप करने के लिए

s.toSet[B >: I] 
.toSeq/* Type B >: I*/ 
.sortBy[C](/* some f:B => C */)(/* implicit ordering on C */) 

वहाँ है एक तरह से इस को हल करने:

लेकिन अब क्या गरीब से टाइपकर्ता का सामना करना पड़ रहा है देखो। लेकिन यह एक बहुत ही जटिल खोज हो जाता है, और यह अभी संकलक से संभाल सकता है। तो यह आपको इनपुट प्रकार के साथ फ़ंक्शन में मदद करने के लिए कहता है ताकि वह उस बिंदु पर B जानता हो (और फिर इसे toSet पर प्रसारित कर सकता है)।

लेकिन तुम, अगर आप चाहते हैं, यह पता स्तरों पर मदद कर सकते हैं:

s.toSet[I].toSeq.sortBy(_.i) 
s.toSet.toSeq.sortBy[Int](_.i) 

या आप इसे करने के लिए प्रदर्शन करके यह मदद कर सकते हैं कि यह बाद में प्रकार पर विचार की जरूरत नहीं है जब सबसे अच्छा मैच उठा पहले के प्रकार के साथ:

{ val temp = s.toSet; temp }.toSeq.sortBy(_.i) 
s.toSet match { case x => x.toSeq.sortBy(_.i) } 
+0

रेक्स, उस ज्ञान के लिए धन्यवाद, जो मैं चाहता था। इस तरह के उत्तरों न केवल समस्या हल करता है, यह मुझे एक गहरी समझ देता है कि क्या हो रहा है। आपका बहुत बहुत धन्यवाद! क्या करुणा है, कोई केवल एक बार ऊपर उठा सकता है: डी –

0

यह प्रकार अनुमान के साथ कुछ करने जैसा लगता है, मुझे काफी अच्छी तरह से पता नहीं है।

+0

हाँ, मुझे पता है कि समस्या को दूर करने के लिए, लेकिन यह मेरे मामले में क्यों जारी रहता है? यह सहजता से नहीं है। –

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