7

यहां एक साधारण प्रजननकर्ता है, जहां मैं एक "कम्यूटिव" जोड़ी प्रकार को परिभाषित करता हूं जो एक निहित रीडरिंग रूपांतरण के साथ आता है। f फ़ंक्शन करने के लिए तर्क पूर्व-मौजूदा नामित मान (उदाहरण में t) में लागू होने पर तर्क को संकलक द्वारा लागू किया गया है। हालांकि, अगर मैं f को सीधे शाब्दिक CommutativePair पर कॉल करने का प्रयास करता हूं, तो यह एक प्रकार की त्रुटि के साथ विफल रहता है। संकलक उस मामले में अंतर्निहित पुनरीक्षण रूपांतरण लागू नहीं कर रहा है।स्कैला अंतर्निहित रूपांतरण कुछ शर्तों के तहत आवेदन कर रहा है लेकिन अन्य नहीं

object repro { 
    import scala.language.implicitConversions 

    case class CommutativePair[A, B](a: A, b: B) 

    object CommutativePair { 
    // Support a kind of commutative behavior via an implicit reordering 
    implicit def reorderPair[B, A](pair: CommutativePair[B, A]) = 
     CommutativePair(pair.b, pair.a) 
    } 

    // The idea is to allow a call to 'f' with Pair[Int, String] as well, 
    // via implicit reorder. 
    def f(p: CommutativePair[String, Int]) = p.toString 

    val t = CommutativePair(3, "c") 

    // This works: the implicit reordering is applied 
    val r1 = f(t) 

    // This fails to compile: the implicit reordering is ignored by the compiler 
    val r2 = f(CommutativePair(3, "c")) 
} 
+0

टाइप अनुमान विफल होने लगता है; जब आप CommutativePair में [Int, String] जोड़ते हैं तो यह फिर से संकलित होता है। –

+0

@LodewijkBogaards, सहमत हैं, मैं इसे स्कैला कंपाइलर बग के रूप में रिपोर्ट करने पर विचार कर रहा हूं, लेकिन यह देखने का इंतजार कर रहा हूं कि मुझे किस प्रकार के उत्तर मिलते हैं। – eje

+0

आपको करना चाहिए। मैंने 2.11.7 में अपना कोड चलाया और मुझे एक ही समस्या मिली। हालांकि मैं कल्पना कर सकता हूं कि संकलक को इससे परेशानी हो रही है, इसे काम करना चाहिए। –

उत्तर

2

मेरा मानना ​​है कि यह स्केला अनुमान की सीमा, जिस क्रम में यह समाधान के लिए खोज करता से शुरू हो रहा मार रहा है। पहली स्थिति में:

val t = CommutativePair(3, "c") 

अनुमान, CommutativePair[Int,String] के प्रकार बंद कर दिया गया है क्योंकि यह केवल एक ही है कि मानकों के आधार पर काम कर सकता है। इसलिए, जब कॉल:

val r1 = f(t) 

यह पर Commutative[Int,String] = = Commutative[String,Int], तो यह implicits की खोज करने वाले प्रकार मेल नहीं खाता हो जाता है और इसके बाद के संस्करण एक पाता है।

दूसरे मामले में, स्केला प्रकार यह पता लगाने की, बाहर से अपनी तरह से काम कर रहा कोशिश कर रहा है:

val r2 = f(CommutativePair(3, "c")) 
  • सबसे पहले, यह निर्धारित करता है कि f, Commutative[String,Int] रखना चाहिए।
  • फिर, यह CommutativePair(...,...)Commutative[String,Int] होना चाहिए (क्योंकि, इसे इसके पैरामीटर से अभी तक यह नहीं पता चला है)।
  • अब यह पैरामीटर को CommutativePair(...) पर देखता है और उन्हें गलत प्रकार लगता है। लेकिन यह अंतर्निहित रूपांतरण को ट्रिगर नहीं करेगा क्योंकि ऐसा लगता है कि विसंगति पैरामीटर में है, पूरे CommutativePair(...) पर नहीं।

दरअसल, टाइप पैरा को लॉक करना (स्पष्ट रूप से उन्हें पास करके या पहले वैल को बाध्य करके) त्रुटि को हल करता है।

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