पैटर्न मिलान में विधि और वर्ग प्रकार के मापदंडों के प्रकार के बीच अंतर


9

जब एक पैरामीटर संलग्नक वर्ग से आता है तो पैटर्न मिलान कार्य अलग-अलग तरीके से क्यों होता है? उदाहरण के लिए,

trait Base[T]
case class Derived(v: Int) extends Base[Int]

class Test[A] {
  def method(arg: Base[A]) = {
    arg match {
      case Derived(_) => 42
    }
  }
}

त्रुटि देता है

constructor cannot be instantiated to expected type;
 found   : A$A87.this.Derived
 required: A$A87.this.Base[A]
      case Derived(_) => 42
           ^

जब यह Aविधि प्रकार पैरामीटर है, तब सफलतापूर्वक इसका संकलन करता है

class Test {
  def method[A](arg: Base[A]) = {
    arg match {
      case Derived(_) => 42
    }
  }
}

प्रश्न डैनियल के विश्लेषण पर आधारित है , जिसका उपयोग मैं इसी तरह के प्रश्न का उत्तर देने का प्रयास करता था ।

जवाबों:


4

मेरे पास 100% पूर्ण उत्तर नहीं है, लेकिन मेरे पास एक संकेतक है जो आपके लिए पर्याप्त हो सकता है।

स्काला कंपाइलर GADTs (सामान्यीकृत बीजगणितीय डेटा प्रकार) के साथ एक विशेष तरीके से व्यवहार करता है। कुछ मामलों को विशेष हैंडलिंग के साथ हल किया जाता है, कुछ मामलों को अनसुलझा कर दिया जाता है। डोट्टी अधिकांश छिद्रों को भरने की कोशिश कर रही है, और यह पहले से ही संबंधित मुद्दों को हल कर चुका है , हालांकि अभी भी काफी कुछ खुले हुए हैं।

स्केल 2 कंपाइलर में विशेष जीएडीटी हैंडलिंग का विशिष्ट उदाहरण आपके उपयोग के मामले से संबंधित है। यदि हम एक नज़र डालें:

def method[A](arg: Base[A]) = {
  arg match {
    case Derived(_) => 42
  }
}

और हम स्पष्ट रूप से वापसी प्रकार की घोषणा करते हैं A:

def method[A](arg: Base[A]): A 

यह ठीक संकलन होगा। आपकी आईडीई शिकायत कर सकती है, लेकिन संकलक इसे जाने देगा। विधि का कहना है कि यह एक रिटर्न देता है A, लेकिन पैटर्न मिलान मामले में मूल्यांकन करता है Int, जो सैद्धांतिक रूप से संकलन नहीं करना चाहिए। हालांकि, कंपाइलर में GADTs की विशेष हैंडलिंग यह ठीक है, क्योंकि उस विशेष पैटर्न में मिलान शाखा Aको एक होने के लिए "निश्चित" किया गया है Int(क्योंकि हम Derivedजिस पर मेल खाते हैं वह एक हैBase[Int] )।

GADT (हमारे मामले में A) के लिए सामान्य प्रकार के पैरामीटर को कहीं न कहीं घोषित किया जाना चाहिए। और यहाँ दिलचस्प हिस्सा है - विशेष संकलक हैंडलिंग केवल तभी काम करता है जब इसे एन्क्लोज़िंग विधि के प्रकार पैरामीटर के रूप में घोषित किया जाता है । यदि यह एक प्रकार के सदस्य या संलग्नक गुण / वर्ग के एक प्रकार के पैरामीटर से आ रहा है, तो यह संकलित नहीं करता है, जैसा कि आपने खुद देखा था।

यही कारण है कि मैंने कहा कि यह 100% पूर्ण उत्तर नहीं है - मैं एक ठोस स्थान (जैसे आधिकारिक विनिर्देश) को इंगित नहीं कर सकता हूं जो इसे ठीक से दस्तावेज करता है। स्काला में जीएडीटी को संभालने के सूत्र ब्लॉगपोस्ट के एक जोड़े के लिए आते हैं, जो वैसे तो महान हैं, लेकिन यदि आप इससे अधिक चाहते हैं तो आपको कंपाइलर कोड में खुद को खोदना होगा। मैंने ठीक वैसा ही करने की कोशिश की, और मुझे लगता है कि यह इस विधि से नीचे आता है , लेकिन अगर आप वास्तव में गहराई में जाना चाहते हैं, तो आप स्काला संकलक कोडबेस के साथ किसी और अनुभवी को पिंग करना चाहते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.