मेरी राय में, दो Function
के बाद सबसे सरल उदाहरण आदेश देने और समानता कर रहे हैं। हालांकि, पहला स्कैला की मानक लाइब्रेरी में कॉन्ट्रैक्ट-वेरिएंट नहीं है, और दूसरा इसमें भी मौजूद नहीं है। तो, मैं स्कालाज़ समकक्षों का उपयोग करने जा रहा हूं: Order और Equal।
अगला, मुझे कुछ वर्ग पदानुक्रम की आवश्यकता है, अधिमानतः एक जो परिचित है और, ज़ाहिर है, इसके ऊपर दोनों अवधारणाओं को इसके लिए समझदारी होनी चाहिए। यदि स्कैला के पास Number
सभी संख्यात्मक प्रकारों का सुपरक्लास था, तो यह सही होगा। दुर्भाग्यवश, इसमें ऐसी कोई बात नहीं है।
तो मैं संग्रहों के साथ उदाहरण बनाने की कोशिश करने जा रहा हूं। इसे सरल बनाने के लिए, बस Seq[Int]
और List[Int]
पर विचार करें। यह स्पष्ट होना चाहिए कि List[Int]
Seq[Int]
का एक उप प्रकार है, यानी List[Int] <: Seq[Int]
।
तो, हम इसके साथ क्या कर सकते हैं? अब मैं कुछ इस तरह कर सकते हैं
implicit val seqOrder = new Order[Seq[Int]] {
def order(a: Seq[Int], b: Seq[Int]) =
if (a.size < b.size) LT
else if (b.size < a.size) GT
else EQ
}
इन परिभाषाओं के साथ
,:
def smaller(a: List[Int], b: List[Int])(implicit ord: Order[List[Int]]) =
if (ord.order(a,b) == LT) a else b
अब मैं Seq[Int]
के लिए एक अंतर्निहित Order
लिखने के लिए जा रहा हूँ: सबसे पहले, के कुछ है कि दो सूचियों तुलना लिखना जाने
scala> smaller(List(1), List(1, 2, 3))
res0: List[Int] = List(1)
नोट मैं एक Order[List[Int]]
के लिए पूछ रहा हूँ कि, लेकिन मैं एक Order[Seq[Int]]
गुजर रहा हूँ। इसका मतलब है कि Order[Seq[Int]] <: Order[List[Int]]
। यह देखते हुए कि Seq[Int] >: List[Int]
, यह केवल भिन्नता के कारण संभव है।
अगला प्रश्न यह है: क्या इसका कोई अर्थ है?
चलो smaller
फिर से विचार करें। मैं पूर्णांक की दो सूचियों की तुलना करना चाहता हूं। स्वाभाविक रूप से, जो कुछ सूचियों की तुलना करता है वह स्वीकार्य है, लेकिन दो Seq[Int]
की तुलना में कुछ ऐसा तर्क है जो स्वीकार्य है?
seqOrder
की परिभाषा में ध्यान दें कि चीजों की तुलना कैसे की जा रही है पैरामीटर पैरामीटर। जाहिर है, List[Int]
Seq[Int]
की अपेक्षा रखने वाले किसी पैरामीटर के लिए पैरामीटर हो सकता है। उस से कुछ ऐसा है जो Seq[Int]
की तुलना में कुछ ऐसा है जो List[Int]
की तुलना में कुछ स्वीकार्य है: वे दोनों एक ही पैरामीटर के साथ उपयोग किए जा सकते हैं।
रिवर्स के बारे में क्या? मान लीजिए कि मेरे पास एक विधि थी जिसकी तुलना केवल ::
(सूची का विपक्ष) की तुलना में की गई थी, जो Nil
के साथ List
का एक उप प्रकार है। मैं स्पष्ट रूप से इसका उपयोग नहीं कर सका, क्योंकि smaller
तुलना करने के लिए Nil
प्राप्त कर सकता है। यह इस प्रकार है कि Order[List[Int]]
के बजाय Order[::[Int]]
का उपयोग नहीं किया जा सकता है।
की समानता के लिए आगे बढ़ना है, और इसके लिए एक विधि लिखें:
def equalLists(a: List[Int], b: List[Int])(implicit eq: Equal[List[Int]]) = eq.equal(a, b)
क्योंकि Order
फैली Equal
, मैं इसे ऊपर एक ही निहित के साथ उपयोग कर सकते हैं:
scala> equalLists(List(4, 5, 6), List(1, 2, 3)) // we are comparing lengths!
res3: Boolean = true
तर्क यहाँ है वही है। कुछ भी जो बता सकता है कि दो Seq[Int]
वही हैं, जाहिर है, यह भी बताएं कि दो List[Int]
समान हैं या नहीं। उस से, यह Equal[Seq[Int]] <: Equal[List[Int]]
का पालन करता है, जो सच है क्योंकि Equal
अनुबंध-भिन्नता है।
डैनियल स्पिवाक का http: // stackoverflow का उत्तर देखें।कॉम/प्रश्न/663254/स्कैला-कॉन्वर्सिस-contravariance-question – sourcedelica
... क्योंकि कोई भी असली दुनिया में कार्यों का उपयोग नहीं करता है? =) –