बीजीय डेटा प्रकार क्या समस्या को हल करते हैं?


18

निष्पक्ष चेतावनी, मैं कार्यात्मक प्रोग्रामिंग के लिए नया हूं इसलिए मैं कई बुरी धारणाओं को पकड़ सकता हूं।

मैं बीजगणितीय प्रकारों के बारे में सीख रहा हूं। कई कार्यात्मक भाषाएं उन्हें लगती हैं, और वे पैटर्न मिलान के साथ संयोजन में काफी उपयोगी हैं। हालांकि, वे वास्तव में किस समस्या का समाधान करते हैं? मैं इस तरह सी # में एक प्रतीत होता है (की तरह) बीजीय प्रकार लागू कर सकते हैं:

public abstract class Option { }
public class None : Option { }
public class Some<T> : Option
{
    public T Value { get; set; }
}

var result = GetSomeValue();
if(result is None)
{
}
else
{
}

लेकिन मुझे लगता है कि अधिकांश सहमत होंगे कि यह ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग का कमी है, और आपको कभी ऐसा नहीं करना चाहिए। तो क्या कार्यात्मक प्रोग्रामिंग सिर्फ एक क्लीनर सिंटैक्स जोड़ती है जो प्रोग्रामिंग की इस शैली को कम सकल लगता है? मैं और क्या भुल रहा हूं?


6
कार्यात्मक प्रोग्रामिंग ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग की तुलना में एक अलग प्रतिमान है।
बेसिल स्टारीनेवविच

@BasileStarynkevitch मुझे एहसास है, लेकिन एफ # जैसी भाषाएं हैं जो दोनों की थोड़ी हैं। सवाल कार्यात्मक भाषाओं के बारे में इतना नहीं है, लेकिन बीजीय डेटा प्रकारों को किस समस्या के बारे में अधिक हल करते हैं।
ConditionRacer

7
क्या होता है जब मैं परिभाषित करता हूं class ThirdOption : Option{}और आपको वह स्थान देता है new ThirdOption()जहां आप उम्मीद करते थे Someया None?
आमोन

1
@ आम भाषाएं जो सम प्रकार की होती हैं उनमें आम तौर पर इसे अस्वीकार करने के तरीके होते हैं। उदाहरण के लिए, हास्केल परिभाषित करता है data Maybe a = Just a | Nothing( data Option a = Some a | Noneआपके उदाहरण में समतुल्य ): आप तीसरे केस पोस्ट-हॉक को नहीं जोड़ सकते। जब आप अपने दिखाए गए तरीके से C # में इम प्रकार का अनुकरण कर सकते हैं, तो यह सबसे सुंदर नहीं है।
मार्टिअन

1
मुझे लगता है कि यह कम है "ADTs क्या समस्या हल करते हैं" और अधिक "ADTs चीजों के करीब पहुंचने का एक अलग तरीका है"।
गणितीयऑक्रिड

जवाबों:


44

इंटरफेस और वंशानुक्रम वाली कक्षाएं एक खुली दुनिया पेश करती हैं: कोई भी एक नए प्रकार का डेटा जोड़ सकता है। किसी दिए गए इंटरफ़ेस के लिए, दुनिया भर में इसे लागू करने वाली कक्षाएं हो सकती हैं, विभिन्न फाइलों में, विभिन्न परियोजनाओं में, विभिन्न कंपनियों में। वे डेटा संरचनाओं में मामलों को जोड़ना आसान बनाते हैं, लेकिन क्योंकि इंटरफ़ेस के कार्यान्वयन को विकेंद्रीकृत किया जाता है, इसलिए इंटरफ़ेस में एक नई विधि जोड़ना मुश्किल है। एक बार एक सार्वजनिक इंटरफ़ेस, यह मूल रूप से जमे हुए है। सभी संभव कार्यान्वयनों को कोई नहीं जानता है।

बीजगणितीय डेटा प्रकार उस के लिए दोहरे हैं, वे बंद हैं । डेटा के सभी मामलों को एक ही स्थान पर सूचीबद्ध किया गया है और संचालन न केवल वेरिएंट को पूरी तरह से सूचीबद्ध कर सकते हैं, उन्हें ऐसा करने के लिए प्रोत्साहित किया जाता है। नतीजतन एक बीजीय डेटा प्रकार पर संचालित एक नया फ़ंक्शन लिखना तुच्छ है: बस लानत फ़ंक्शन लिखें। बदले में, नए मामलों को जोड़ना जटिल है क्योंकि आपको मूल रूप से संपूर्ण कोड आधार पर जाने और प्रत्येक का विस्तार करने की आवश्यकता है match। रूस्ट मानक पुस्तकालय में इंटरफेस के साथ स्थिति के समान, एक नया संस्करण जोड़ना एक सार्वजनिक परिवर्तन (सार्वजनिक प्रकारों के लिए) है।

ये अभिव्यक्ति की समस्या के दो पहलू हैं । बीजगणितीय डेटा प्रकार उनके लिए एक अधूरा समाधान है, लेकिन ऐसा OOP है। दोनों के फायदे हैं कि डेटा के कितने मामले हैं, उन मामलों में कितनी बार परिवर्तन होता है, और कितनी बार संचालन बढ़ाया या बदला जाता है। (यही कारण है कि कई आधुनिक भाषाएं दोनों, या कुछ समान प्रदान करती हैं, या अधिक शक्तिशाली और अधिक जटिल तंत्रों के लिए सीधे जाती हैं जो दृष्टिकोणों को कम करने की कोशिश करती हैं।)


क्या आप एक कंपाइलर त्रुटि प्राप्त करते हैं यदि आप एक मैच को अपडेट करने में विफल रहते हैं, या क्या यह केवल रन टाइम पर है जो आपको पता है?
इयान

6
@ इयान की अधिकांश कार्यात्मक भाषाएँ वैधानिक रूप से टाइप की जाती हैं और पैटर्न मिलान की थकावट की जाँच करती हैं। हालांकि, अगर "कैच ऑल" पैटर्न है, तो कंपाइलर खुश है भले ही फ़ंक्शन को अपना काम करने के लिए नए मामले से निपटना पड़े। इसके अलावा, आपको सभी आश्रित कोड को फिर से जमा करना होगा, आप केवल एक पुस्तकालय को संकलित नहीं कर सकते हैं और इसे पहले से निर्मित एप्लिकेशन में पुनः लिंक कर सकते हैं।

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

@usr कोई भी भाषा मुझे सही समाधान के प्रयासों के बारे में पता नहीं है, या तो संकलक समझता है कि यह संपूर्ण है या आप एक पकड़-सभी मामले को जोड़ने के लिए मजबूर हैं जहां आप दुर्घटनाग्रस्त हो जाते हैं और जल जाते हैं। मैं सैट के संबंध के बारे में नहीं जानता, हालांकि, क्या आपके पास कमी के लिए लिंक है? भले ही, वास्तविक कार्यक्रमों में लिखे गए वास्तविक कोड के लिए, थकावट की जांच बाल्टी में एक बूंद है।

कल्पना कीजिए कि आप एन बुलियन पर मेल खा रहे हैं। फिर आप (जैसे, बी, _, डी, ...) मैच क्लॉस जोड़ते हैं। कैच-ऑल केस तब है! क्लॉज़ 1 &&! क्लॉज़ 2 && .... जो मुझे SAT की तरह दिखता है।
usr

12

तो क्या कार्यात्मक प्रोग्रामिंग सिर्फ एक क्लीनर सिंटैक्स जोड़ती है जो प्रोग्रामिंग की इस शैली को कम सकल लगता है?

यह शायद एक सरलीकरण है, लेकिन हां।

मैं और क्या भुल रहा हूं?

आइए स्पष्ट करें कि बीजीय डेटा प्रकार क्या हैं (इस बढ़िया लिंक को आपको हास्केल के रूप में सारांशित करते हुए ):

  • एक योग प्रकार जो कहता है "यह मान ए या बी हो सकता है"।
  • एक उत्पाद प्रकार जो कहता है "यह मान ए और बी दोनों है "।

आपका उदाहरण केवल पहले के साथ वास्तव में काम करता है।

जो आप शायद याद कर रहे हैं वह यह है कि इन दो बुनियादी कार्यों को प्रदान करके, कार्यात्मक भाषाएं आपको सब कुछ बनाने देती हैं। C # के पास संरचनाएं, कक्षाएं, एनम, उन के शीर्ष पर जेनरिक, और नियमों के ढेर हैं कि यह कैसे व्यवहार करें।

मदद करने के लिए कुछ सिंटैक्स के साथ संयुक्त, कार्यात्मक भाषा इन दो रास्तों के संचालन को विघटित कर सकती है, प्रकारों के लिए एक स्वच्छ, सरल और सुरुचिपूर्ण दृष्टिकोण प्रदान करती है।

बीजीय डेटा प्रकार क्या समस्या को हल करते हैं?

वे किसी भी अन्य प्रकार की प्रणाली के समान समस्या को हल करते हैं: "यहां उपयोग करने के लिए कौन से मूल्य कानूनी हैं?" - वे सिर्फ इसके लिए एक अलग तरीका अपनाते हैं।


4
आपका अंतिम वाक्य किसी को यह बताने की तरह है कि "जहाज हवाई जहाज के समान समस्या को हल करते हैं: परिवहन - वे बस इसके लिए एक अलग दृष्टिकोण लेते हैं"। यह पूरी तरह से सही कथन है, और एक बहुत बेकार भी है।
user541686

@ फरहाद - मुझे लगता है कि यह थोड़ा अधिक है।
तेलस्तीन

1
इसमें कोई संदेह नहीं है कि आप बीजीय डेटा प्रकारों को ठीक समझते हैं, लेकिन आपकी बुलेटेड सूची ("A sum type is ..." और "A product type is is ...") संघ और चौराहे के प्रकारों के विवरण की तरह दिखता है, जो नहीं हैं योग और उत्पाद प्रकार के रूप में एक ही बात।
पियोन

6

आपको यह जानकर आश्चर्य हो सकता है कि विकल्प के साथ काम करने के लिए पैटर्न मिलान को सबसे मुहावरेदार तरीका नहीं माना जाता है। इसके बारे में अधिक जानकारी के लिए स्काला के विकल्पों का प्रलेखन देखें । मुझे यकीन नहीं है कि इतने सारे एफपी ट्यूटोरियल इस उपयोग को क्यों प्रोत्साहित करते हैं।

ज्यादातर आप जो याद कर रहे हैं, वहाँ विकल्पों का आसान काम करने के लिए बनाए गए कार्यों का एक पूरा गुच्छा है। स्काला डॉक्स से मुख्य उदाहरण पर विचार करें:

val name: Option[String] = request getParameter "name"
val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
println(upper getOrElse "")

सूचना कैसे mapऔर filterप्रत्येक बिंदु आप चाहे पर जांच किए बिना ही आप विकल्प पर कार्रवाई श्रृंखला, जाने Noneया नहीं। फिर अंत में, आप getOrElseएक डिफ़ॉल्ट मान निर्दिष्ट करने के लिए उपयोग करते हैं। किसी भी बिंदु पर आप कुछ "सकल" नहीं कर रहे हैं जैसे कि चेकिंग प्रकार। किसी भी अपरिहार्य प्रकार की जाँच लाइब्रेरी में आंतरिक रूप से की जाती है। हास्केल के पास गुदा कार्यों का अपना सेट है, न कि उन कार्यों के बड़े सेट का उल्लेख करने के लिए जो किसी भी मोनाड या फ़ंक्टर पर काम करेंगे।

अन्य बीजीय डेटा प्रकारों में उनके साथ काम करने के लिए अपने स्वयं के मुहावरेदार तरीके हैं, और ज्यादातर मामलों में पैटर्न मिलान टोटेम पोल पर कम है। इसी तरह, जब आप अपने स्वयं के प्रकार बनाते हैं, तो आपको उनसे काम करने के लिए समान कार्य प्रदान करने की अपेक्षा की जाती है।

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