जब स्केल पैरामीटर निर्दिष्ट नहीं है, तो Scala नीचे के प्रकार को क्यों प्रभावित करता है?

Nov 23 2020

मुझे आश्चर्य है कि अगर कोई इस विशेष मामले में नीचे के नियम की व्याख्या कर सकता है, और सबसे महत्वपूर्ण बात यह तर्कसंगत / निहितार्थ है?

case class E[A, B](a: A) // class E
E(2) // E[Int,Nothing] = E(2)

ध्यान दें कि मैं लिख सकता था E[Int](2)। मेरे लिए क्या मायने रखता है कि दूसरे पैरामीटर प्रकार को उदाहरण के लिए Nothingकहने के बजाय (यानी निचला प्रकार) होने का अनुमान क्यों लगाया जाता है Any? क्यों और क्या तर्कसंगत / निहितार्थ है?

बस कुछ संदर्भ देने के लिए, यह या तो की परिभाषा से संबंधित है और यह वाम और अधिकार के लिए कैसे काम करता है। दोनों को पैटर्न के अनुसार परिभाषित किया गया है

final case class X[+A, +B](value: A) extends Either[A, B]

जहां आप इसे कहते हैं, उसे तुरंत बता देते हैं Right[Int](2)और प्रकार का Right[Nothing, Int]विस्तार और विस्तार से होता हैEither[Nothing, Int]

EDIT1

यहाँ स्थिरता है, लेकिन मैं अभी भी तर्कसंगत समझ सकता हूं। नीचे एक ही परिभाषा के साथ एक गर्भ-वार पैरामीट है:

case class E[A, -B](a: A)// class E
E(2) // E[Int, Any] = E(2)

इसलिए हमारे पास एक ही बात है कि जब वह गर्भ-विचरण करता है, तो उसके आसपास दूसरा तरीका है, और यह सभी व्यवहार या अनुमान नियम, सुसंगत बनाता है। हालाँकि इसके लिए तर्कसंगत मुझे यकीन नहीं है ...।

Anyसह-वारिएंट / इनवेरिएंट और Nothingकॉन्ट्रा-वेरिएंट के विपरीत विपरीत नियम क्यों नहीं हैं ?

EDIT2

@Slouc उत्तर के प्रकाश में, जो अच्छी समझ रखते हैं, मैं अभी भी समझ रहा हूँ कि संकलक क्या कर रहा है और क्यों कर रहा है। नीचे दिया गया उदाहरण मेरे भ्रम को स्पष्ट करता है

val myleft = Left("Error") // Left[String,Nothing] = Left(Error)
myleft map { (e:Int) => e * 4} // Either[String,Int] = Left(Error)

  1. पहले कंपाइलर कुछ इस प्रकार से तय करता है कि "निश्चित काम के लिए" @slouc के निष्कर्ष का पुन: उपयोग करने के लिए (यद्यपि फ़ंक्शन के संदर्भ में अधिक समझ में आता है)Left[String,Nothing]
  2. अगले संकलन myleftटाइप या तो होने का अनुमान है [स्ट्रिंग, इंट]

दी गई नक्शा परिभाषा def map[B](f: A => B): Either[E, B], (e:Int) => e * 4केवल आपूर्ति की जा सकती है यदि myleftवास्तव में Left[String,Int]या हैEither[String,Int]

तो दूसरे शब्दों में, मेरा सवाल Nothingयह है कि अगर इसे बाद में बदलना है तो टाइप को ठीक करने का क्या मतलब है ।

वास्तव में निम्नलिखित संकलन नहीं है

val aleft: Left[String, Nothing] = Left[String, Int]("Error")

type mismatch;
found   : scala.util.Left[String,Int]
required: Left[String,Nothing]
val aleft: Left[String, Nothing] = Left[String, Int]("Error")

तो मैं एक प्रकार का अनुमान क्यों लगाऊंगा, जो सामान्य रूप से मुझे उस प्रकार के चर पर कुछ भी करने के लिए अवरुद्ध करेगा ( लेकिन अनुमान के अनुसार निश्चित कार्यों के लिए ), अंततः उस प्रकार को बदलने के लिए, इसलिए मैं उस चर के साथ कुछ कर सकता हूं अनुमान लगाया हुआ प्रकार।

EDIT3

Edit2 थोड़ी गलतफहमी है और @slouc उत्तर और टिप्पणियों में सब कुछ स्पष्ट किया गया है।

जवाब

4 slouc Nov 23 2020 at 17:33
  • सहसंयोजक:
    प्रकार F[+A]और संबंध को देखते हुए A <: B, फिर निम्नलिखित हैं:F[A] <: F[B]

  • विरोधाभासी:
    प्रकार F[-A]और संबंध को देखते हुए A <: B, फिर निम्नलिखित हैं:F[A] >: F[B]

यदि कंपाइलर सटीक प्रकार का अनुमान नहीं लगा सकता है, तो यह संकेतन के मामले में सबसे कम संभव प्रकार को हल करेगा और कंट्राविरियन के मामले में उच्चतम संभव प्रकार होगा।

क्यों?

यह एक बहुत ही महत्वपूर्ण नियम है जब यह उप -करण में विचरण की बात आती है। इसे स्काला से निम्न डेटा प्रकार के उदाहरण पर दिखाया जा सकता है:

trait Function1[Input-, Output+]

सामान्यतया, जब एक प्रकार को फ़ंक्शन / विधि मापदंडों में रखा जाता है, तो इसका मतलब है कि यह तथाकथित "कंट्रावेरिएंट स्थिति" है। यदि यह फ़ंक्शन / विधि रिटर्न मानों में उपयोग किया जाता है, तो यह तथाकथित "सहसंयोजक स्थिति" में है। यदि यह दोनों में है, तो यह अपरिवर्तनीय है।

अब, इस पद की शुरुआत से नियमों को देखते हुए, हम यह निष्कर्ष निकालते हैं:

trait Food
trait Fruit extends Food
trait Apple extends Fruit

def foo(someFunction: Fruit => Fruit) = ???

हम आपूर्ति कर सकते हैं

val f: Food => Apple = ???
foo(f)

फ़ंक्शन इसके fलिए एक मान्य विकल्प है someFunction:

  • Foodका एक सुपरटाइप है Fruit(इनपुट के विपरीत)
  • Appleका एक उपप्रकार है Fruit(उत्पादन का सहसंयोजक)

हम इसे इस तरह से प्राकृतिक भाषा में समझा सकते हैं:

"विधि fooको एक फ़ंक्शन की आवश्यकता होती है जो ए Fruitऔर उत्पादन कर सकती है Fruit। इसका मतलब fooकुछ Fruitहोगा और एक फ़ंक्शन की आवश्यकता होगी जो इसे खिला सकती है, और कुछ Fruitवापस की उम्मीद कर सकती है। यदि यह एक फ़ंक्शन प्राप्त करता है Food => Apple, तो सब कुछ ठीक है - यह अभी भी इसे खिला सकता है Fruit( क्योंकि फ़ंक्शन कोई भी भोजन लेता है), और यह प्राप्त कर सकता है Fruit(सेब फल हैं, इसलिए अनुबंध का सम्मान किया जाता है)।

अपनी प्रारंभिक दुविधा पर वापस आ रहा है, उम्मीद है कि यह बताता है कि क्यों, बिना किसी अतिरिक्त जानकारी के, संकलक सहसंयोजक प्रकारों के लिए न्यूनतम संभव प्रकार का और सबसे अधिक संभावित प्रकार का उपयोग करेगा। अगर हम एक फंक्शन को सप्लाई करना चाहते हैं foo, तो एक ऐसा है जिसे हम जानते हैं कि वह निश्चित रूप से काम करता है Any => Nothing:।

सामान्य रूप से भिन्न ।

स्काला प्रलेखन में भिन्नता ।

स्काला में विचरण के बारे में लेख (पूर्ण प्रकटीकरण: मैंने इसे लिखा है)।

संपादित करें:

मुझे लगता है कि मुझे पता है कि आप क्या भ्रमित कर रहे हैं।

जब आप इन्स्टैंट करते हैं Left[String, Nothing], तो आपको बाद में mapइसे फंक्शन Int => Whateverया String => Whatever, या के साथ अनुमति दी जाती है Any => Whatever। यह पहले से समझाया गया फंक्शन इनपुट के कंट्रोवर्सी के कारण है। इसलिए आपके mapकाम करता है।

"बाद में इसे बदलने के लिए कुछ भी नहीं करने के लिए प्रकार को ठीक करने का क्या मतलब है?"

मुझे लगता है कि संकलक के मामले में अज्ञात प्रकार को ठीक करने वाले कंपाइलर के चारों ओर अपना सिर लपेटना थोड़ा कठिन है Nothing। जब यह कोविरियन के Anyमामले में अज्ञात प्रकार को ठीक करता है , तो यह अधिक प्राकृतिक लगता है (यह "कुछ भी" हो सकता है)। कोविरियन और कॉन्ट्रोवर्सी के द्वंद्व की वजह से पहले समझाया गया था, वही तर्क कॉन्ट्रैवियर Nothingऔर कॉवेरिएन्ट के लिए लागू होता है Any

1 DmytroMitin Nov 23 2020 at 20:54

यह यूगीन बर्माको द्वारा स्काला में संकलन-समय और रनटाइम मीटप्रोग्रामिंग के एकीकरण का एक उद्धरण है

https://infoscience.epfl.ch/record/226166 (पृष्ठ 95-96)

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

बाधाओं को इकट्ठा करने के बाद, टाइपेकचर एक कदम-दर-चरण प्रक्रिया शुरू करता है, जो प्रत्येक चरण पर, असमानताओं में एक निश्चित परिवर्तन लागू करने की कोशिश करता है, एक समान, अभी तक माना जाता है कि असमानताओं की सरल प्रणाली। प्रकार की खोज का लक्ष्य मूल असमानताओं को समानता में बदलना है जो मूल प्रणाली के एक अद्वितीय समाधान का प्रतिनिधित्व करते हैं।

अधिकांश समय, प्रकार का अनुमान सफल होता है। उस स्थिति में, अनुपलब्ध प्रकार के तर्क समाधान द्वारा दर्शाए गए प्रकारों के लिए अनुमानित हैं।

हालांकि, कभी-कभी प्रकार की विफलता विफल हो जाती है। उदाहरण के लिए, जब एक प्रकार का पैरामीटर Tप्रेत होता है, अर्थात विधि के शब्द मापदंडों में अप्रयुक्त होता है, तो इसकी असमानताओं की प्रणाली में केवल प्रविष्टि क्रमशः L <: T <: Uकहां Lऔर Uइसके निचले और ऊपरी हिस्से में होती है। यदि L != U, इस असमानता का एक अनूठा समाधान नहीं है, और इसका मतलब है कि प्रकार की विफलता की विफलता।

जब प्रकार की विफलता विफल हो जाती है, अर्थात जब यह किसी भी अधिक परिवर्तन के कदम उठाने में असमर्थ होता है और इसकी कार्यशील स्थिति में अभी भी कुछ असमानताएं होती हैं, तो टाइपकास्टर गतिरोध को तोड़ देता है। यह सभी अभी तक निर्जन प्रकार के तर्कों को लेता है, अर्थात जिनके चर अभी भी असमानताओं का प्रतिनिधित्व करते हैं, और उन्हें जबरन कम से कम करते हैं, अर्थात उन्हें अपनी निचली सीमा के बराबर बनाते हैं। यह एक परिणाम उत्पन्न करता है जहां कुछ प्रकार के तर्क ठीक अनुमान लगाए जाते हैं, और कुछ को मनमाने ढंग से प्रकारों के साथ बदल दिया जाता है। उदाहरण के लिए, असंबंधित प्रकार के मापदंडों का अनुमान है Nothing, जो स्काला शुरुआती के लिए भ्रम का एक सामान्य स्रोत है।

आप स्काला में टाइप इंट्रेंस के बारे में अधिक जान सकते हैं:

ह्यूबर्ट प्लोसिनिकज़क डिस्क्रिप्टिंग स्थानीय प्रकार का आविष्कार https://infoscience.epfl.ch/record/214757

गिलियूम मार्टर्स स्काला 3, टाइप इंट्रेंस एंड यू! https://www.youtube.com/watch?v=lMvOykNQ4zs

Guillaume Martres Dotty और प्रकार: अब तक की कहानी https://www.youtube.com/watch?v=YIQjfCKDR5A

स्लाइड्स http://guillaume.martres.me/talks/

डोट्टी में अलेक्जेंडर बोरुच - ग्रुसज़ेकी जीएडीटी https://www.youtube.com/watch?v=VV9lPg3fNl8