इंटरसेक्शन टाइप
Type systems |
---|
General concepts |
Major categories |
|
Minor categories |
प्रकार सिद्धांत में, एक प्रतिच्छेदन प्रकार को उन मानों के लिए आवंटित किया जा सकता है जिन्हें दोनों प्रकारों को सौंपा जा सकता है और प्रकार . यह मान प्रतिच्छेदन प्रकार दिया जा सकता है एक प्रतिच्छेदन प्रकार प्रणाली में.[1]
आम तौर पर, यदि दो प्रकार के मानों की श्रेणियाँ ओवरलैप होती हैं, तो दो श्रेणियों के प्रतिच्छेदन से संबंधित मान को इन दो प्रकारों के प्रतिच्छेदन प्रकार को निर्दिष्ट किया जा सकता है। इस तरह के मान को दोनों प्रकारों में से किसी एक की अपेक्षा वाले कार्यों के लिए तर्क के रूप में सुरक्षित रूप से पारित किया जा सकता है।
उदाहरण के लिए, Java_(प्रोग्रामिंग_भाषा) क्लास में Boolean
दोनों को लागू करता है Serializable
और यह Comparable
इंटरफ़ेस. इसलिए, एक प्रकार की वस्तु Boolean
प्रकार के तर्क की अपेक्षा वाले कार्यों में सुरक्षित रूप से पारित किया जा सकता है Serializable
और प्रकार के तर्क की अपेक्षा करने वाले कार्यों के लिए Comparable
.
प्रतिच्छेदन प्रकार समग्र डेटा प्रकार हैं। उत्पाद प्रकारों के समान, उनका उपयोग किसी वस्तु को कई प्रकार निर्दिष्ट करने के लिए किया जाता है। हालाँकि, उत्पाद प्रकार टुपल्स को निर्दिष्ट किए जाते हैं, ताकि प्रत्येक टुपल तत्व को एक विशेष उत्पाद प्रकार घटक सौंपा जा सके। इसकी तुलना में, प्रतिच्छेदन प्रकार की अंतर्निहित वस्तुएं आवश्यक रूप से मिश्रित नहीं होती हैं। प्रतिच्छेदन प्रकारों का एक प्रतिबंधित रूप शोधन प्रकार है।
Function_overloading का वर्णन करने के लिए इंटरसेक्शन प्रकार उपयोगी होते हैं।[2] उदाहरण के लिए, यदि number => number
फ़ंक्शन का प्रकार है जो किसी संख्या को तर्क के रूप में लेता है और एक संख्या लौटाता है, और string => string
एक फ़ंक्शन का प्रकार है जो एक स्ट्रिंग को एक तर्क के रूप में लेता है और एक स्ट्रिंग लौटाता है, फिर इन दो प्रकारों के प्रतिच्छेदन का उपयोग उन (अतिभारित) कार्यों का वर्णन करने के लिए किया जा सकता है जो एक या दूसरे कार्य करते हैं, इस पर आधारित है कि उन्हें किस प्रकार का इनपुट दिया गया है।
समसामयिक प्रोग्रामिंग भाषाएँ, जिनमें सीलोन (प्रोग्रामिंग भाषा), फ्लो, जावा (प्रोग्रामिंग भाषा), स्काला (प्रोग्रामिंग भाषा), माइक्रोसॉफ्ट टाइपस्क्रिप्ट, और Whiley_(प्रोग्रामिंग_भाषा) शामिल हैं (देखें #प्रतिच्छेदन प्रकारों के साथ भाषाओं की तुलना), इंटरफ़ेस को संयोजित करने के लिए प्रतिच्छेदन प्रकारों का उपयोग करें विशिष्टताओं और तदर्थ बहुरूपता को व्यक्त करने के लिए। पैरामीट्रिक बहुरूपता को लागू करते हुए, क्रॉस-कटिंग चिंताओं से वर्ग पदानुक्रम प्रदूषण से बचने और बॉयलरप्लेट कोड को कम करने के लिए चौराहे प्रकारों का उपयोग किया जा सकता है, जैसा कि नीचे #TypeScript उदाहरण में दिखाया गया है।
प्रतिच्छेदन प्रकारों के प्रकार सिद्धांत अध्ययन को प्रतिच्छेदन प्रकार अनुशासन के रूप में जाना जाता है।[3] उल्लेखनीय रूप से, प्रोग्राम समाप्ति को प्रतिच्छेदन प्रकारों का उपयोग करके सटीक रूप से चित्रित किया जा सकता है।[4]
टाइपप्रति उदाहरण
टाइपस्क्रिप्ट प्रतिच्छेदन प्रकारों का समर्थन करता है,[5]प्रकार प्रणाली की अभिव्यक्ति में सुधार और संभावित वर्ग पदानुक्रम आकार को कम करना, निम्नानुसार प्रदर्शित किया गया है।
निम्नलिखित प्रोग्राम कोड कक्षाओं को परिभाषित करता है Chicken
, Cow
, और RandomNumberGenerator
कि प्रत्येक के पास एक विधि है produce
किसी भी प्रकार की वस्तु लौटाना Egg
, Milk
, या number
.
इसके अतिरिक्त, कार्य eatEgg
और drinkMilk
प्रकार के तर्कों की आवश्यकता है Egg
और Milk
, क्रमश।
class Egg { private kind: "Egg" }
class Milk { private kind: "Milk" }
//produces eggs
class Chicken { produce() { return new Egg(); } }
//produces milk
class Cow { produce() { return new Milk(); } }
//produces a random number
class RandomNumberGenerator { produce() { return Math.random(); } }
//requires an egg
function eatEgg(egg: Egg) {
return "I ate an egg.";
}
//requires milk
function drinkMilk(milk: Milk) {
return "I drank some milk.";
}
निम्नलिखित प्रोग्राम कोड तदर्थ बहुरूपता फ़ंक्शन को परिभाषित करता है animalToFood
जो सदस्य फ़ंक्शन को आमंत्रित करता है produce
दी गई वस्तु का animal
.
कार्यक्रम animalToFood
में दो प्रकार के एनोटेशन हैं, अर्थात् ((_: Chicken) => Egg)
और ((_: Cow) => Milk)
, इंटरसेक्शन टाइप कंस्ट्रक्टर के माध्यम से जुड़ा हुआ है &
.
विशेष रूप से, animalToFood
जब किसी प्रकार के तर्क पर लागू किया जाता है Chicken
प्रकार का ऑब्जेक्ट लौटाता है Egg
, और जब किसी प्रकार के तर्क पर लागू किया जाता है Cow
प्रकार का ऑब्जेक्ट लौटाता है Milk
.
आदर्श रूप से, animalToFood
किसी भी वस्तु पर लागू नहीं होना चाहिए (संभवतः संयोग से) a produce
तरीका।
//given a chicken, produces an egg; given a cow, produces milk
let animalToFood: ((_: Chicken) => Egg) & ((_: Cow) => Milk) =
function (animal: any) {
return animal.produce();
};
अंत में, निम्नलिखित प्रोग्राम कोड उपरोक्त परिभाषाओं के टाइप_सेफ्टी उपयोग को प्रदर्शित करता है।
var chicken = new Chicken();
var cow = new Cow();
var randomNumberGenerator = new RandomNumberGenerator();
console.log(chicken.produce()); //Egg { }
console.log(cow.produce()); //Milk { }
console.log(randomNumberGenerator.produce()); //0.2626353555444987
console.log(animalToFood(chicken)); //Egg { }
console.log(animalToFood(cow)); //Milk { }
//console.log(animalToFood(randomNumberGenerator)); //ERROR: Argument of type 'RandomNumberGenerator' is not assignable to parameter of type 'Cow'
console.log(eatEgg(animalToFood(chicken))); //I ate an egg.
//console.log(eatEgg(animalToFood(cow))); //ERROR: Argument of type 'Milk' is not assignable to parameter of type 'Egg'
console.log(drinkMilk(animalToFood(cow))); //I drank some milk.
//console.log(drinkMilk(animalToFood(chicken))); //ERROR: Argument of type 'Egg' is not assignable to parameter of type 'Milk'
उपरोक्त प्रोग्राम कोड में निम्नलिखित गुण हैं:
- पंक्तियाँ 1-3 वस्तुएँ बनाती हैं
chicken
,cow
, औरrandomNumberGenerator
अपने-अपने प्रकार के। - पंक्तियाँ 5-7 पहले से बनाई गई वस्तुओं के लिए संबंधित परिणामों को प्रिंट करती हैं (टिप्पणियों के रूप में प्रदान की जाती हैं) जब आह्वान किया जाता है
produce
. - पंक्ति 9 (सम्मान 10) विधि के प्रकार के सुरक्षित उपयोग को दर्शाती है
animalToFood
के लिए आवेदन कियाchicken
(सम्मान.cow
). - पंक्ति 11, यदि टिप्पणी नहीं की गई, तो संकलन के समय एक प्रकार की त्रुटि होगी। यद्यपि का कार्यान्वयन
animalToFood
का आह्वान कर सकता हैproduce
उसकि विधिrandomNumberGenerator
, एनोटेशन का प्रकारanimalToFood
इसकी अनुमति नहीं देता. यह अभीष्ट अर्थ के अनुरूप हैanimalToFood
. - पंक्ति 13 (सम्मान 15) दर्शाती है कि लागू करना
animalToFood
कोchicken
(सम्मान.cow
) का परिणाम एक प्रकार की वस्तु में होता हैEgg
(सम्मान.Milk
). - पंक्ति 14 (सम्मान 16) दर्शाती है कि आवेदन करना
animalToFood
कोcow
(सम्मान.chicken
) का परिणाम किसी प्रकार की वस्तु में नहीं होता हैEgg
(सम्मान.Milk
). इसलिए, यदि टिप्पणी नहीं की गई, तो पंक्ति 14 (सम्मान 16) के परिणामस्वरूप संकलन समय पर एक प्रकार की त्रुटि होगी।
विरासत से तुलना
उपरोक्त न्यूनतम उदाहरण को इनहेरिटेंस_(ऑब्जेक्ट-ओरिएंटेड_प्रोग्रामिंग) का उपयोग करके महसूस किया जा सकता है, उदाहरण के लिए कक्षाएं प्राप्त करके Chicken
और Cow
बेस क्लास से Animal
.
हालाँकि, बड़ी सेटिंग में, यह नुकसानदेह हो सकता है।
वर्ग पदानुक्रम में नई कक्षाओं का परिचय क्रॉस-कटिंग चिंताओं के लिए आवश्यक रूप से उचित नहीं है, या शायद बिल्कुल असंभव है, उदाहरण के लिए बाहरी पुस्तकालय का उपयोग करते समय।
कल्पना कीजिए, उपरोक्त उदाहरण को निम्नलिखित वर्गों के साथ बढ़ाया जा सकता है:
- एक वर्ग
Horse
जिसमें कोई नहीं हैproduce
तरीका; - एक वर्ग
Sheep
जिसमें एक हैproduce
विधि वापसीWool
; - एक वर्ग
Pig
जिसमें एक हैproduce
विधि, जिसका उपयोग केवल एक बार किया जा सकता है, वापस लौटनाMeat
.
इसके लिए अतिरिक्त कक्षाओं (या इंटरफेस) की आवश्यकता हो सकती है जो निर्दिष्ट करती है कि क्या उत्पादन विधि उपलब्ध है, क्या उत्पादन विधि भोजन लौटाती है, और क्या उत्पादन विधि का बार-बार उपयोग किया जा सकता है। कुल मिलाकर, यह वर्ग पदानुक्रम को प्रदूषित कर सकता है।
बत्तख टाइपिंग से तुलना
उपरोक्त न्यूनतम उदाहरण पहले से ही दिखाता है कि दिए गए परिदृश्य को समझने के लिए डक टाइपिंग कम उपयुक्त है।
जबकि कक्षा RandomNumberGenerator
इसमें शामिल है produce
विधि, वस्तु randomNumberGenerator
के लिए वैध तर्क नहीं होना चाहिए animalToFood
.
उपरोक्त उदाहरण को डक टाइपिंग का उपयोग करके महसूस किया जा सकता है, उदाहरण के लिए एक नया क्षेत्र शुरू करके argumentForAnimalToFood
कक्षाओं के लिए Chicken
और Cow
यह दर्शाता है कि संबंधित प्रकार की वस्तुएं वैध तर्क हैं animalToFood
.
हालाँकि, इससे न केवल संबंधित वर्गों का आकार बढ़ेगा (विशेष रूप से समान तरीकों की शुरूआत के साथ)। animalToFood
), लेकिन इसके संबंध में एक गैर-स्थानीय दृष्टिकोण भी है animalToFood
.
फ़ंक्शन ओवरलोडिंग से तुलना
उपरोक्त उदाहरण को फ़ंक्शन ओवरलोडिंग का उपयोग करके महसूस किया जा सकता है, उदाहरण के लिए दो तरीकों को लागू करके animalToFood(animal: Chicken): Egg
और animalToFood(animal: Cow): Milk
.
टाइपस्क्रिप्ट में, ऐसा समाधान दिए गए उदाहरण के लगभग समान है।
अन्य प्रोग्रामिंग भाषाओं, जैसे Java_(प्रोग्रामिंग_भाषा) को अतिभारित पद्धति के विशिष्ट कार्यान्वयन की आवश्यकता होती है।
इससे या तो कोड दोहराव या बॉयलरप्लेट कोड हो सकता है।
आगंतुक पैटर्न की तुलना
उपरोक्त उदाहरण को विज़िटर पैटर्न का उपयोग करके महसूस किया जा सकता है।
इसे लागू करने के लिए प्रत्येक पशु वर्ग की आवश्यकता होगी accept
इंटरफ़ेस को कार्यान्वित करने वाली किसी वस्तु को स्वीकार करने की विधि AnimalVisitor
(गैर-स्थानीय बॉयलरप्लेट कोड जोड़ना)।
कार्यक्रम animalToFood
के रूप में साकार किया जाएगा visit
के कार्यान्वयन की विधि AnimalVisitor
.
दुर्भाग्य से, इनपुट प्रकार के बीच संबंध (Chicken
या Cow
) और परिणाम प्रकार (Egg
या Milk
) का प्रतिनिधित्व करना कठिन होगा।
सीमाएँ
एक ओर, वर्ग पदानुक्रम में नई कक्षाएं (या इंटरफेस) पेश किए बिना किसी फ़ंक्शन में विभिन्न प्रकारों को स्थानीय रूप से एनोटेट करने के लिए प्रतिच्छेदन प्रकारों का उपयोग किया जा सकता है। दूसरी ओर, इस दृष्टिकोण के लिए सभी संभावित तर्क प्रकारों और परिणाम प्रकारों को स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता होती है। यदि किसी फ़ंक्शन के व्यवहार को एकीकृत इंटरफ़ेस, पैरामीट्रिक बहुरूपता, या डक टाइपिंग द्वारा सटीक रूप से निर्दिष्ट किया जा सकता है, तो प्रतिच्छेदन प्रकारों की वर्बोज़ प्रकृति प्रतिकूल है। इसलिए, प्रतिच्छेदन प्रकारों को मौजूदा विनिर्देश विधियों का पूरक माना जाना चाहिए।
आश्रित प्रतिच्छेदन प्रकार
एक आश्रित प्रतिच्छेदन प्रकार, दर्शाया गया , एक आश्रित प्रकार है जिसमें प्रकार चर शब्द पर निर्भर हो सकता है .[6] विशेष रूप से, यदि कोई शब्द आश्रित प्रतिच्छेदन प्रकार है , फिर पद दोनों प्रकार के हैं और प्रकार , कहाँ वह प्रकार है जो पद चर की सभी घटनाओं को प्रतिस्थापित करने से उत्पन्न होता है में शब्द द्वारा .
स्काला उदाहरण
स्काला (प्रोग्रामिंग भाषा) प्रकार की घोषणाओं का समर्थन करती है [7] वस्तु सदस्यों के रूप में। यह किसी ऑब्जेक्ट सदस्य के प्रकार को किसी अन्य सदस्य के मान पर निर्भर करने की अनुमति देता है, जिसे पथ-निर्भर प्रकार कहा जाता है।[8]
उदाहरण के लिए, निम्नलिखित प्रोग्राम टेक्स्ट स्काला विशेषता को परिभाषित करता है Witness
, जिसका उपयोग सिंगलटन पैटर्न को लागू करने के लिए किया जा सकता है।[9]
trait Witness {
type T
val value: T {}
}
उपरोक्त विशेषता Witness
सदस्य घोषित करता है T
, जिसे इसके मान और सदस्य के रूप में एक प्रकार निर्दिष्ट किया जा सकता है value
, जिसे प्रकार का मान निर्दिष्ट किया जा सकता है T
.
निम्नलिखित प्रोग्राम टेक्स्ट एक ऑब्जेक्ट को परिभाषित करता है booleanWitness
उपरोक्त विशेषता के उदाहरण के रूप में Witness
.
जो वस्तु booleanWitness
प्रकार को परिभाषित करता है T
जैसा Boolean
और मूल्य value
जैसा true
.
उदाहरण के लिए, क्रियान्वित करना System.out.println(booleanWitness.value)
प्रिंट true
कंसोल पर.
object booleanWitness extends Witness {
type T = Boolean
val value = true
}
होने देना सदस्य वाली वस्तुओं का प्रकार (विशेष रूप से, एक रिकॉर्ड (कंप्यूटर विज्ञान)) हो प्रकार का .
उपरोक्त उदाहरण में, object booleanWitness
आश्रित प्रतिच्छेदन प्रकार निर्दिष्ट किया जा सकता है .
तर्क इस प्रकार है. जो वस्तु booleanWitness
सदस्य है T
वह प्रकार असाइन किया गया है Boolean
इसके मूल्य के रूप में.
तब से Boolean
एक प्रकार है, वस्तु है booleanWitness
प्रकार है .
इसके अतिरिक्त, वस्तु booleanWitness
सदस्य है value
वह मान असाइन किया गया है true
प्रकार का Boolean
.
के मूल्य के बाद से booleanWitness.T
है Boolean
, जो वस्तु booleanWitness
प्रकार है .
कुल मिलाकर, वस्तु booleanWitness
प्रतिच्छेदन प्रकार है .
अत: स्व-संदर्भ को निर्भरता, वस्तु के रूप में प्रस्तुत करना booleanWitness
आश्रित प्रतिच्छेदन प्रकार है .
वैकल्पिक रूप से, उपरोक्त न्यूनतम उदाहरण को आश्रित रिकॉर्ड प्रकारों का उपयोग करके वर्णित किया जा सकता है।[10] आश्रित प्रतिच्छेदन प्रकारों की तुलना में, आश्रित रिकॉर्ड प्रकार एक सख्ती से अधिक विशिष्ट प्रकार की सैद्धांतिक अवधारणा का गठन करते हैं।[6]
एक प्रकार के परिवार का प्रतिच्छेदन
एक प्रकार के परिवार का एक प्रतिच्छेदन, निरूपित , एक आश्रित प्रकार है जिसमें प्रकार चर शब्द पर निर्भर हो सकता है . विशेष रूप से, यदि कोई शब्द प्रकार है , फिर प्रत्येक पद के लिए प्रकार का , शब्द प्रकार है . इस धारणा को अंतर्निहित आश्रित प्रकार#Pi प्रकार भी कहा जाता है,[11] उस तर्क को देखते हुए टर्म स्तर पर नहीं रखा गया है.
प्रतिच्छेदन प्रकारों वाली भाषाओं की तुलना
Language | Actively developed | Paradigm(s) | Status | Features |
---|---|---|---|---|
C# | Yes[12] | Under discussion[13] | Additionally, generic type parameters can have constraints that require their (monomorphized) type-arguments to implement multiple interfaces, whereupon the runtime type represented by the generic type parameter becomes an intersection-type of all listed interfaces. | |
Ceylon | Yes[14] | Supported[15] |
| |
F# | Yes[16] | Under discussion[17] | ? | |
Flow | Yes[18] | Supported[19] |
| |
Forsythe | No | Supported[20] |
| |
Java | Yes[21] | Supported[22] |
| |
PHP | Yes[23] | Supported[24] |
| |
Scala | Yes[25] | Supported[26][27] |
| |
TypeScript | Yes[28] | Supported[5] |
| |
Whiley | Yes[29] | Supported[30] | ? |
संदर्भ
- ↑ Barendregt, Henk; Coppo, Mario; Dezani-Ciancaglini, Mariangiola (1983). "एक फ़िल्टर लैम्ब्डा मॉडल और प्रकार असाइनमेंट की पूर्णता". Journal of Symbolic Logic. 48 (4): 931–940. doi:10.2307/2273659. JSTOR 2273659. S2CID 45660117.
- ↑ Palsberg, Jens (2012). "Overloading is NP-Complete". तर्क और कार्यक्रम शब्दार्थ. Lecture Notes in Computer Science. Vol. 7230. pp. 204–218. doi:10.1007/978-3-642-29485-3_13. ISBN 978-3-642-29484-6.
- ↑ Henk Barendregt; Wil Dekkers; Richard Statman (20 June 2013). लैम्ब्डा कैलकुलस प्रकार के साथ. Cambridge University Press. pp. 1–. ISBN 978-0-521-76614-2.
- ↑ Ghilezan, Silvia (1996). "प्रतिच्छेदन प्रकारों के साथ मजबूत सामान्यीकरण और टाइपेबिलिटी". Notre Dame Journal of Formal Logic. 37 (1): 44–52. doi:10.1305/ndjfl/1040067315.
- ↑ 5.0 5.1 "Intersection Types in TypeScript". Retrieved 2019-08-01.
- ↑ 6.0 6.1 Kopylov, Alexei (2003). "Dependent intersection: A new way of defining records in type theory". 18th IEEE Symposium on Logic in Computer Science. LICS 2003. IEEE Computer Society. pp. 86–95. CiteSeerX 10.1.1.89.4223. doi:10.1109/LICS.2003.1210048.
- ↑ "स्कैला में घोषणाएँ टाइप करें". Retrieved 2019-08-15.
- ↑ Amin, Nada; Grütter, Samuel; Odersky, Martin; Rompf, Tiark; Stucki, Sandro (2016). "The essence of dependent object types" (PDF). Lecture Notes in Computer Science. A List of Successes That Can Change the World - Essays Dedicated to Philip Wadler on the Occasion of His 60th Birthday. Springer. 9600: 249–272. doi:10.1007/978-3-319-30936-1_14. ISBN 978-3-319-30935-4.
- ↑ "स्काला आकारहीन पुस्तकालय में सिंगलटन". GitHub. Retrieved 2019-08-15.
- ↑ Pollack, Robert (2000). "गणितीय संरचना का प्रतिनिधित्व करने के लिए निर्भरता से टाइप किए गए रिकॉर्ड". Theorem Proving in Higher Order Logics, 13th International Conference. TPHOLs 2000. Springer. pp. 462–479. doi:10.1007/3-540-44659-1_29.
- ↑ Stump, Aaron (2018). "बोधगम्यता से आश्रित प्रतिच्छेदन के माध्यम से प्रेरण तक". Annals of Pure and Applied Logic. 169 (7): 637–655. doi:10.1016/j.apal.2018.03.002.
- ↑ "C# Guide". Retrieved 2019-08-08.
- ↑ "Discussion: Union and Intersection types in C Sharp". GitHub. Retrieved 2019-08-08.
- ↑ "Eclipse Ceylon: Welcom to Ceylon". Retrieved 2019-08-08.
- ↑ "Intersection Types in Ceylon". Retrieved 2019-08-08.
- ↑ "F# Software Foundation". Retrieved 2019-08-08.
- ↑ "Add Intersection Types to F Sharp". GitHub. Retrieved 2019-08-08.
- ↑ "Flow: A Static Type Checker for JavaScript". Retrieved 2019-08-08.
- ↑ "Intersection Type Syntax in Flow". Retrieved 2019-08-08.
- ↑ Reynolds, J. C. (1988). Preliminary design of the programming language Forsythe.
- ↑ "Java Software". Retrieved 2019-08-08.
- ↑ "IntersectionType (Java SE 12 & JDK 12)". Retrieved 2019-08-01.
- ↑ "php.net".
- ↑ "PHP.Watch - PHP 8.1: Intersection Types".
- ↑ "The Scala Programming Language". Retrieved 2019-08-08.
- ↑ "Compound Types in Scala". Retrieved 2019-08-01.
- ↑ "Intersection Types in Dotty". Retrieved 2019-08-01.
- ↑ "TypeScript - JavaScript that scales". Retrieved 2019-08-01.
- ↑ "Whiley: an Open Source Programming Language with Extended Static Checking". Retrieved 2019-08-01.
- ↑ "Whiley language specification" (PDF). Retrieved 2019-08-01.