वास्तव में हास्केल प्रकार प्रणाली इतनी प्रतिष्ठित (बनाम कहना, जावा) क्या बनाती है?


204

मैं हास्केल सीखना शुरू कर रहा हूं । मैं इसके लिए बहुत नया हूं, और मैं अपने मूल निर्माणों के बारे में जानने के लिए ऑनलाइन पुस्तकों के एक जोड़े के माध्यम से पढ़ रहा हूं।

एक 'मेम' जो इससे परिचित लोगों ने अक्सर बात की है, वह है "संपूर्ण" यदि यह संकलन करता है, तो यह काम करेगा * "बात - जो मुझे लगता है कि टाइप सिस्टम की ताकत से संबंधित है।

मैं यह समझने की कोशिश कर रहा हूं कि वास्तव में हास्केल इस संबंध में अन्य सांख्यिकीय रूप से टाइप की गई भाषाओं से बेहतर क्यों हैं

एक और रास्ता रखो, मैं जावा में मानता हूं, आप कुछ ऐसा ArrayList<String>()करने के लिए दफनाने जैसा कुछ कर सकते हैं जो वास्तव में होना चाहिए ArrayList<Animal>()। यहाँ जघन्य बात यह है कि आपके stringसम्‍मिलित हैं elephant, giraffe, आदि, और यदि कोई डालता है Mercedes- आपका कंपाइलर आपकी मदद नहीं करेगा।

अगर मैं किया करते ArrayList<Animal>()समय में कुछ बाद में किसी समय है, तो, अगर मैं तय मेरी कार्यक्रम, जानवरों के बारे में वास्तव में नहीं है, यह वाहनों के बारे में है, तो मैं, बदल सकते हैं कहते हैं, एक समारोह है कि पैदा करता है ArrayList<Animal>निर्माण करने के लिए ArrayList<Vehicle>और मेरे आईडीई मुझे हर जगह वहाँ बताना चाहिए एक संकलन विराम है।

मेरी धारणा यह है कि यह एक मजबूत प्रकार की प्रणाली से लोगों का मतलब है , लेकिन यह मेरे लिए स्पष्ट नहीं है कि हास्केल बेहतर क्यों है। एक और तरीका रखो, आप अच्छा या बुरा जावा लिख ​​सकते हैं, मेरा मानना ​​है कि आप हास्केल में ऐसा कर सकते हैं (यानी स्ट्रिंग्स / इन्ट्स में सामान जो वास्तव में प्रथम श्रेणी के डेटा प्रकार होने चाहिए)।

मुझे संदेह है कि मुझे कुछ महत्वपूर्ण / बुनियादी याद आ रही है।
मुझे अपने तरीकों की त्रुटि दिखा कर बहुत खुशी होगी!


31
मैं वास्तविक उत्तर लिखने की तुलना में लोगों को अधिक जानकार होने दूंगा, लेकिन इसका सार यह है: सी # जैसी स्थिर-टाइप की भाषाओं में एक प्रकार की प्रणाली है जो आपको रक्षात्मक कोड लिखने में मदद करने का प्रयास करती है ; टाइप सिस्टम जैसे हास्केल की कोशिश आपको सही (यानी साबित) कोड लिखने में मदद करती है । काम पर मूल सिद्धांत उन चीजों को स्थानांतरित कर रहा है जिन्हें संकलन चरण में जांचा जा सकता है; हास्केल संकलन के समय अधिक चीजों की जांच करता है ।
रॉबर्ट हार्वे

8
हास्केल के बारे में मुझे ज्यादा जानकारी नहीं है, लेकिन मैं जावा के बारे में बोल सकता हूं। हालांकि यह दृढ़ता से टाइप किया हुआ प्रतीत होता है , फिर भी यह आपको "जघन्य" चीजें करने की अनुमति देता है जैसा आपने कहा था। लगभग हर गारंटी के लिए जावा अपने प्रकार के सिस्टम के बारे में बनाता है, इसके चारों ओर एक रास्ता है।

12
मुझे नहीं पता कि सभी उत्तर Maybeकेवल अंत की ओर क्यों उल्लेख करते हैं। अगर मुझे सिर्फ एक बात चुननी थी कि अधिक लोकप्रिय भाषाओं को हास्केल से उधार लेना चाहिए, तो यही होगा। यह एक बहुत ही सरल विचार है (इसलिए सैद्धांतिक दृष्टिकोण से बहुत दिलचस्प नहीं है), लेकिन यह अकेले हमारे काम को इतना आसान बना देगा।
पॉल

1
यहाँ महान जवाब होंगे, लेकिन सहायता करने के प्रयास में, अध्ययन पर हस्ताक्षर। वे मनुष्यों और कार्यक्रमों को इस तरह से कार्यक्रमों के बारे में तर्क करने की अनुमति देते हैं जो यह बताएंगे कि जावा कैसे मधुर मध्य पुन: प्रकारों में है।
माइकल ईस्टर

6
निष्पक्षता के लिए मुझे यह बताना चाहिए कि "संपूर्ण यदि यह संकलित करता है, तो यह काम करेगा" एक नारा है न कि वास्तव में एक शाब्दिक कथन। हां, हम हास्केल प्रोग्रामर जानते हैं कि टाइप चेकर को पास करने से शुद्धता के कुछ सीमित धारणाओं के लिए शुद्धता का एक अच्छा मौका मिलता है, लेकिन यह निश्चित रूप से एक शाब्दिक और सार्वभौमिक "सच" कथन नहीं है!
टॉम एलिस

जवाबों:


230

यहाँ Haskell में उपलब्ध प्रकार प्रणाली सुविधाओं की एक अनियंत्रित सूची है और या तो अनुपलब्ध है या जावा में कम अच्छा है (मेरी जानकारी के लिए, जो कि वास्तव में कमजोर wrt जावा है)

  • सुरक्षा । हास्केल के प्रकार में बहुत अच्छे "प्रकार की सुरक्षा" गुण हैं। यह बहुत विशिष्ट है, लेकिन यह अनिवार्य रूप से इसका मतलब है कि कुछ प्रकार के मूल्यों को अन्य प्रकार में परिवर्तित नहीं किया जा सकता है। यह कभी-कभी उत्परिवर्तन के साथ होता है (देखें OCaml का मान प्रतिबंध )
  • बीजगणितीय डेटा प्रकार । हास्केल के प्रकारों में अनिवार्य रूप से उच्च विद्यालय के गणित के समान संरचना होती है। यह अपमानजनक रूप से सरल और सुसंगत है, फिर भी, जैसा कि यह पता चला है, जितना संभव हो उतना शक्तिशाली हो सकता है। यह केवल एक प्रकार की प्रणाली के लिए एक महान आधार है।
    • डेटाटाइप-जेनेरिक प्रोग्रामिंग । यह सामान्य प्रकार ( सामान्यीकरण देखें ) के समान नहीं है । इसके बजाय, प्रकार की संरचना की सादगी के कारण जैसा कि पहले यह कोड लिखना अपेक्षाकृत आसान है जो उस संरचना पर उदारतापूर्वक संचालित होता है। बाद में मैं इस बारे में बात करता हूं कि Eqहस्केल कंपाइलर द्वारा उपयोगकर्ता-परिभाषित प्रकार के लिए uality जैसी कोई चीज ऑटो-व्युत्पन्न कैसे हो सकती है। अनिवार्य रूप से जिस तरह से यह होता है वह किसी भी उपयोगकर्ता-परिभाषित प्रकार के अंतर्निहित सामान्य, सरल संरचना पर चलता है और इसे मूल्यों के बीच मेल खाता है - संरचनात्मक समानता का एक बहुत ही प्राकृतिक रूप।
  • पारस्परिक रूप से पुनरावर्ती प्रकार । यह गैर-तुच्छ प्रकार लिखने का एक अनिवार्य घटक है।
    • नेस्टेड प्रकार । यह आपको वैरिएबल पर पुनरावर्ती प्रकारों को परिभाषित करने की अनुमति देता है जो विभिन्न प्रकारों पर पुनरावृत्ति करते हैं। उदाहरण के लिए, एक प्रकार का संतुलित पेड़ है data Bt a = Here a | There (Bt (a, a))। के मान्य मूल्यों के बारे में ध्यान से सोचें Bt aऔर ध्यान दें कि यह कैसे काम करता है। यह युक्तियुक्त है!
  • सामान्यीकरण । यह लगभग बहुत मूर्खतापूर्ण है कि एक प्रकार की प्रणाली में नहीं है (अहम, आपको देखकर, गो)। प्रकार चर की धारणा और कोड के बारे में बात करने की क्षमता होना महत्वपूर्ण है जो उस चर की पसंद से स्वतंत्र है। हिंडले मिलनर एक प्रकार की प्रणाली है जो सिस्टम एफ से ली गई है। हास्केल का प्रकार सिस्टम एचएम टाइपिंग का विस्तार है और सिस्टम एफ अनिवार्य रूप से सामान्यीकरण का चूल्हा है। मेरे कहने का तात्पर्य यह है कि हास्केल की कहानी बहुत अच्छी है।
  • सार प्रकार । हास्केल की कहानी यहाँ महान नहीं है, बल्कि गैर-मौजूद भी नहीं है। ऐसे प्रकार लिखना संभव है जिनके पास एक सार्वजनिक इंटरफ़ेस है लेकिन एक निजी कार्यान्वयन है। यह हमें बाद के समय में कार्यान्वयन कोड में परिवर्तन करने की अनुमति देता है, और महत्वपूर्ण बात यह है कि चूंकि यह हास्केल में सभी ऑपरेशन का आधार है, इसलिए "जादू" प्रकार लिखें, जिसमें अच्छी तरह से परिभाषित इंटरफेस हैं जैसे IO। जावा में वास्तव में एक अच्छा सार प्रकार की कहानी है, ईमानदार होने के लिए, लेकिन मुझे नहीं लगता कि जब तक कि इंटरफेसेस अधिक लोकप्रिय नहीं हो जाते, तब तक यह सच था।
  • परिमाणवाद । हास्केल मूल्यों का कोई सार्वभौमिक संचालन नहीं है । जावा इसे संदर्भ समानता और हैशिंग जैसी चीजों के साथ उल्लंघन करता है और यहां तक ​​कि जोर-जबरदस्ती के साथ। इसका मतलब यह है कि आप उन प्रकारों के बारे में नि: शुल्क प्रमेय प्राप्त करते हैं जो आपको अपने प्रकार से पूरी तरह से एक उल्लेखनीय डिग्री के संचालन या मूल्य का अर्थ जानने की अनुमति देते हैं --- कुछ प्रकार ऐसे होते हैं जिनमें केवल बहुत कम संख्या में निवासी हो सकते हैं।
  • उच्चतर प्रकार के प्रकार पेचीदा चीज़ों को एन्कोडिंग करते समय सभी प्रकार दिखाते हैं। फ़नकार / एपेरेटिव / मोनाड, फोल्डेबल / ट्रैवर्सेबल, संपूर्ण mtlप्रभाव टाइपिंग सिस्टम, सामान्यीकृत फ़नकार फ़िक्सपॉइंट। यह सूची लम्बी होते चली जाती है। बहुत सी चीजें हैं जो उच्च प्रकार पर सबसे अच्छी तरह से व्यक्त की जाती हैं और अपेक्षाकृत कुछ प्रकार की प्रणालियां भी उपयोगकर्ता को इन चीजों के बारे में बात करने की अनुमति देती हैं।
  • कक्षाएं टाइप करें । यदि आप लॉजिक के रूप में टाइप सिस्टम के बारे में सोचते हैं - जो उपयोगी है - तो आपको अक्सर चीजों को साबित करने की मांग की जाती है। कई मामलों में यह अनिवार्य रूप से लाइन शोर है: इसका केवल एक सही उत्तर हो सकता है और यह प्रोग्रामर को यह बताने के लिए समय और प्रयास की बर्बादी है। टंकक आपके लिए प्रमाण उत्पन्न करने के लिए हास्केल का एक तरीका है। अधिक ठोस शब्दों में, यह आपको सरल "प्रकार समीकरण सिस्टम" को हल करने देता है जैसे "किस प्रकार पर हम (+)चीजों को पहले से ही इरादा कर रहे हैं Integer,, ठीक है! चलो अब सही कोड को इनलाइन करें!"। अधिक जटिल प्रणालियों में आप अधिक दिलचस्प बाधाओं की स्थापना कर सकते हैं।
    • बाधा गणना । हास्केल में बाधाएं - जो टाइपकास्टल प्रोलॉग सिस्टम में पहुंचने के लिए तंत्र हैं - संरचनात्मक रूप से टाइप की गई हैं। यह सबसिडी संबंध का एक बहुत ही सरल रूप देता है जो आपको सरल से जटिल बाधाओं को इकट्ठा करने देता है। पूरा mtlपुस्तकालय इसी विचार पर आधारित है।
    • व्युत्पन्न करना । आदेश में ड्राइव करने के लिए canonicity typeclass प्रणाली की यह कमी प्रयोक्ता परिभाषित प्रकार का दृष्टांत चाहिए वर्णन करने के लिए अक्सर तुच्छ कोड का एक बहुत कुछ लिखने के लिए आवश्यक है। हास्केल प्रकारों की बहुत ही सामान्य संरचना के लिए करें, यह अक्सर बॉयलर से आपके लिए यह करने के लिए पूछना संभव है।
    • टाइप क्लास प्रोलॉग । हास्केल टाइप क्लास सॉल्वर-जो सिस्टम उन "प्रमाणों" को उत्पन्न कर रहा है, जिन्हें मैंने पहले उल्लेख किया है- अनिवार्य रूप से अच्छे शब्दार्थ गुणों के साथ प्रोलॉग का अपंग रूप है। इसका मतलब यह है कि आप वास्तव में बालों वाली चीजों को प्रोलॉग में सांकेतिक शब्दों में बदलना कर सकते हैं और उम्मीद कर सकते हैं कि उन्हें संकलन के समय ही संभाल लिया जाएगा। एक अच्छा उदाहरण एक प्रमाण के लिए हल हो सकता है कि दो विषम सूची समान हैं यदि आप आदेश के बारे में भूल जाते हैं - वे समकक्ष विषम "सेट" हैं।
    • मल्टी-पैरामीटर प्रकार कक्षाएं और कार्यात्मक निर्भरताएं । ये बेस टाइपेकल प्रोलॉग के लिए बड़े पैमाने पर उपयोगी शोधन हैं। यदि आप प्रोलॉग जानते हैं, तो आप कल्पना कर सकते हैं कि जब आप एक से अधिक चर की भविष्यवाणी लिख सकते हैं तो अभिव्यंजक शक्ति कितनी बढ़ जाती है।
  • बहुत अच्छा अनुमान । हिंडले मिलनर प्रकार की प्रणालियों पर आधारित भाषाओं में बहुत अच्छा अनुमान है। एचएम के पास स्वयं पूर्ण प्रतिक्षेप है जिसका अर्थ है कि आपको कभी भी एक प्रकार का चर लिखने की आवश्यकता नहीं है। हास्केल 98, हास्केल का सबसे सरल रूप, पहले से ही कुछ बहुत ही दुर्लभ परिस्थितियों में बाहर फेंकता है। आम तौर पर, आधुनिक हास्केल एचएम में अधिक शक्ति जोड़ते हुए और उपयोगकर्ताओं द्वारा शिकायत करने पर देखने के दौरान धीरे-धीरे पूर्ण निष्कासन के स्थान को कम करने का एक प्रयोग रहा है। लोग बहुत कम ही शिकायत करते हैं - हास्केल का अनुमान बहुत अच्छा है।
  • बहुत, बहुत, केवल बहुत कमजोर उपप्रकार । मैंने पहले उल्लेख किया है कि टाइपकास्ट प्रोलॉग से बाधा प्रणाली में संरचनात्मक उपप्रकार की धारणा है। हास्केल में उपप्रकार का एकमात्र रूप है । उप-तर्क और तर्क के लिए उप-प्रकार भयानक है। यह उन समस्याओं में से प्रत्येक को काफी कठिन बनाता है (समानता की प्रणाली के बजाय असमानताओं की एक प्रणाली)। यह वास्तव में गलतफहमी के लिए भी आसान है (सबटाइपिंग के समान ही उपवर्ग है? निश्चित रूप से नहीं! लेकिन लोग बहुत बार भ्रमित होते हैं और कई भाषाएं उस भ्रम में सहायता करती हैं! हम यहां कैसे समाप्त हुए? मुझे लगता है कि कोई भी कभी भी एलएसपी की जांच नहीं करता है।)
    • ध्यान दें कि हाल ही में (2017 की शुरुआत में) स्टीवन डोलन ने अपनी थीसिस MLSub पर प्रकाशित की , जो कि एक प्रकार का ML और Hindley-Milner प्रकार का निष्कर्ष है जिसकी एक बहुत अच्छी उपकथा कहानी है ( यह भी देखें )। इससे यह नहीं पता चलता है कि मैंने ऊपर जो लिखा है - अधिकांश सबटाइपिंग सिस्टम टूट गए हैं और खराब निष्कर्ष निकले हैं - लेकिन यह बताता है कि हमने अभी-अभी पूरी तरह से प्रवेश के लिए कुछ आशाजनक तरीकों की खोज की है और बारीकियों को एक साथ निभा सकते हैं। अब, पूरी तरह से स्पष्ट होने के लिए, जावा के उपप्रकार की धारणाएं किसी भी तरह से डोलन के एल्गोरिदम और प्रणालियों का लाभ उठाने में सक्षम नहीं हैं। यह क्या घटाव का मतलब पुनर्विचार की आवश्यकता है।
  • उच्च रैंक प्रकार । मैंने पहले सामान्यीकरण के बारे में बात की थी, लेकिन केवल सामान्यीकरण से अधिक यह उन प्रकारों के बारे में बात करने में सक्षम है जो उनके भीतर सामान्यीकृत चर हैं । उदाहरण के लिए, उच्च क्रम संरचनाओं के बीच एक मानचित्रण जो विचलित होता है ( पैरामीट्रिकिटी देखें ) कि उन संरचनाओं में "समाहित" क्या एक प्रकार है (forall a. f a -> g a)। सीधे एचएम में आप इस प्रकार में आयोजित एक समारोह में लिख सकते हैं, लेकिन उच्च रैंक प्रकार के साथ आप एक के रूप में इस तरह के एक समारोह की मांग तर्क तो जैसे: mapFree :: (forall a . f a -> g a) -> Free f -> Free g। ध्यान दें कि aचर केवल तर्क के भीतर ही है। इसका मतलब यह है कि फ़ंक्शन का निश्चित होना यह mapFreeतय करना aहै कि इसका उपयोग करने पर क्या त्वरित है, उपयोगकर्ता का नहीं mapFree
  • अस्तित्व के प्रकार । जबकि उच्च-श्रेणी के प्रकार हमें सार्वभौमिक परिमाणीकरण के बारे में बात करने की अनुमति देते हैं, अस्तित्वगत प्रकार हमें अस्तित्वगत मात्रा के बारे में बात करते हैं: यह विचार कि केवल कुछ अज्ञात प्रकार मौजूद हैं जो कुछ समीकरणों को संतुष्ट करते हैं। यह उपयोगी होने के लिए समाप्त होता है और इसके बारे में अधिक समय तक चलने में लंबा समय लगेगा।
  • परिवारों को टाइप करें । कभी-कभी टंकण तंत्र असुविधाजनक होते हैं क्योंकि हम हमेशा प्रोलॉग में नहीं सोचते हैं। टाइप परिवार हमें टाइपों के बीच सीधे कार्यात्मक संबंध लिखने देते हैं ।
    • बंद प्रकार के परिवार । टाइप परिवार डिफ़ॉल्ट रूप से खुले होते हैं जो कष्टप्रद होता है क्योंकि इसका मतलब है कि जब आप उन्हें किसी भी समय बढ़ा सकते हैं तो आप सफलता की किसी भी उम्मीद के साथ उन्हें "उल्टा" नहीं कर सकते। यह इसलिए है क्योंकि आप इंजेक्शन साबित नहीं कर सकते हैं , लेकिन बंद प्रकार के परिवारों के साथ आप कर सकते हैं।
  • तरह अनुक्रमित प्रकार और पदोन्नति । मैं इस बिंदु पर वास्तव में विदेशी हूं, लेकिन समय-समय पर इनका व्यावहारिक उपयोग होता है। यदि आप एक प्रकार के हैंडल को लिखना चाहते हैं जो या तो खुले हैं या बंद हैं तो आप ऐसा कर सकते हैं। निम्नलिखित स्निपेट में ध्यान दें कि Stateएक बहुत ही सरल बीजीय प्रकार है, जिसके मूल्य इसके प्रकार-स्तर में भी प्रचारित थे। फिर, बाद में, हम के बारे में बात कर सकते हैं प्रकार कंस्ट्रक्टर्स की तरह Handleविशिष्ट पर बहस लेने के रूप में प्रकार की तरह State। यह सभी विवरणों को समझने के लिए भ्रामक है, लेकिन इतना सही भी है।

    data State = Open | Closed
    
    data Handle :: State -> * -> * where
      OpenHandle :: {- something -} -> Handle Open a
      ClosedHandle :: {- something -} -> Handle Closed a
  • रनटाइम प्रकार प्रतिनिधित्व जो काम करते हैं । जावा प्रकार के क्षरण के लिए कुख्यात है और कुछ लोगों के परेडों में बारिश की सुविधा है। टाइप इरेज़र जाने का सही तरीका है, हालाँकि, यदि आपके पास कोई फ़ंक्शन है getRepr :: a -> TypeReprतो आप बहुत कम से कम पैरामीट्रिकिटी का उल्लंघन करते हैं। इससे भी बुरी बात यह है कि यदि यह एक उपयोगकर्ता-जनित फ़ंक्शन है जिसका उपयोग रनटाइम के दौरान असुरक्षित जोर-जबरदस्ती को ट्रिगर करने के लिए किया जाता है ... तो आपको एक बड़े पैमाने पर सुरक्षा चिंता है । हास्केल की Typeableप्रणाली एक सुरक्षित निर्माण की अनुमति देती है coerce :: (Typeable a, Typeable b) => a -> Maybe b। यह प्रणाली Typeableकंपाइलर (और उपयोगकर्ता नहीं) में लागू होने पर निर्भर करती है और हास्केल के टाइपकास्ट तंत्र के बिना इस तरह के अच्छे शब्दार्थ भी नहीं दिए जा सकते हैं और जिन कानूनों का पालन करने की गारंटी है।

केवल इनसे अधिक हालांकि हास्केल के प्रकार प्रणाली का मूल्य भी इस बात से संबंधित है कि भाषा का प्रकार कैसे वर्णन करता है। यहां हास्केल की कुछ विशेषताएं हैं जो टाइप सिस्टम के माध्यम से मूल्य ड्राइव करती हैं।

  • पवित्रता । हास्केल "साइड इफेक्ट" की बहुत, बहुत, बहुत व्यापक परिभाषा के लिए कोई दुष्प्रभाव नहीं होने देता है। यह आपको इनपुट और आउटपुट को नियंत्रित करने वाले प्रकारों के बारे में अधिक जानकारी देने के लिए बाध्य करता है और साइड इफेक्ट्स के बिना इनपुट और आउटपुट में सब कुछ का हिसाब देना चाहिए।
    • आईओ । बाद में, हास्केल पक्ष के बारे में बात करने के लिए एक तरह से की जरूरत प्रभाव के बाद से किसी भी वास्तविक कार्यक्रम, कुछ-तो एक typeclasses के संयोजन, उच्च kinded प्रकार शामिल करना चाहिए और अमूर्त प्रकार एक विशेष, सुपर विशेष प्रकार कहा जाता है का उपयोग कर की धारणा को जन्म दिया है IO aप्रतिनिधित्व करने के लिए साइड-इफेक्टिंग कंप्यूटेशन जिसके परिणामस्वरूप टाइप के मान होते हैं a। यह शुद्ध भाषा के अंदर एम्बेडेड एक बहुत अच्छे प्रभाव प्रणाली की नींव है ।
  • का अभावnull । हर कोई जानता है कि nullआधुनिक प्रोग्रामिंग भाषाओं की अरब डॉलर की गलती है। बीजीय प्रकार, विशेष रूप से केवल एक प्रकार Aको टाइप में बदलकर आपके पास "मौजूद नहीं है" स्थिति को जोड़ने की क्षमता Maybe A, पूरी तरह से समस्या को कम करती है null
  • बहुरूपी पुनरावृत्ति । यह आपको पुनरावर्ती कार्यों को परिभाषित करने देता है जो अपने स्वयं के सामान्यीकरण में प्रत्येक पुनरावर्ती कॉल में विभिन्न प्रकारों का उपयोग करने के बावजूद प्रकार चर को सामान्य करते हैं। इस बारे में बात करना मुश्किल है, लेकिन नेस्टेड प्रकारों के बारे में बात करने के लिए विशेष रूप से उपयोगी है। वापस करने के लिए देखो Bt aपहले से प्रकार और उसके आकार की गणना करने के लिए एक समारोह लिखने की कोशिश: size :: Bt a -> Int। यह थोड़ा size (Here a) = 1और पसंद आएगा size (There bt) = 2 * size bt। परिचालन रूप से यह बहुत जटिल नहीं है, लेकिन ध्यान दें कि sizeपिछले समीकरण में पुनरावर्ती कॉल एक अलग प्रकार पर होता है , फिर भी समग्र परिभाषा में एक सामान्यीकृत प्रकार होता है size :: Bt a -> Int। ध्यान दें कि यह एक विशेषता है जो कुल अनुमान को तोड़ता है, लेकिन यदि आप एक प्रकार का हस्ताक्षर प्रदान करते हैं तो हास्केल इसे अनुमति देगा।

मैं जा सकता था, लेकिन यह सूची आपको शुरू करने के लिए चाहिए और तब-तब।


7
नल एक अरब डॉलर की "गलती" नहीं थी। ऐसे मामले हैं जहां यह संभव नहीं है कि सांख्यिकीय रूप से यह सत्यापित किया जाए कि संभावित रूप से मौजूद किसी भी सार्थक से पहले सूचक को निष्क्रिय नहीं किया जाएगा ; इस तरह के एक मामले में एक प्रयास में फंसाने का प्रयास करने से अक्सर बेहतर होता है कि सूचक शुरू में एक व्यर्थ वस्तु की पहचान करता है। मुझे लगता है कि सबसे बड़ी अशक्त-संबंधी गलती कार्यान्वयन की थी, जो दी जाएगी , पर फंस जाएगी , लेकिन न ही फंस जाएगीchar *p = NULL;*p=1234char *q = p+5678;*q = 1234;
सुपरकैट

37
यह सिर्फ टोनी होरे से उद्धृत किया गया है: en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions । हालांकि मुझे लगता है कि ऐसे समय हैं जब nullपॉइंटर अंकगणित में आवश्यक हैं, मैं इसके बजाय यह कहने के लिए व्याख्या करता हूं कि पॉइंटर अंकगणित आपकी भाषा के शब्दार्थ को होस्ट करने के लिए एक बुरी जगह है न कि नल अभी भी एक गलती नहीं है।
जे। अब्राहमसन

18
@ सुपरकैट, आप वास्तव में अशक्त के बिना एक भाषा लिख ​​सकते हैं। इसे अनुमति देना या न करना एक विकल्प है।
पॉल ड्रेपर

6
@ सुपरकैट - यह समस्या हास्केल में भी मौजूद है, लेकिन एक अलग रूप में। हास्केल सामान्य रूप से आलसी और अपरिवर्तनीय है, और इसलिए आप इसे p = undefinedतब तक लिखने की अनुमति देते हैं जब तक pमूल्यांकन नहीं किया जाता है। अधिक उपयोगी रूप से, आप undefinedकिसी प्रकार के परिवर्तनशील संदर्भ में रख सकते हैं , फिर से जब तक आप इसका मूल्यांकन नहीं करते हैं। अधिक गंभीर चुनौती आलसी गणनाओं के साथ है जो समाप्त नहीं हो सकती है, जो निश्चित रूप से अनिर्दिष्ट है। मुख्य अंतर यह है कि ये सभी स्पष्ट रूप से प्रोग्रामिंग दोष हैं , और साधारण तर्क व्यक्त करने के लिए कभी भी उपयोग नहीं किए जाते हैं।
क्रिश्चियन कोंकले

6
@supercat हास्केल में संदर्भ संदर्भों का पूरी तरह से अभाव है (यह संदर्भात्मक पारदर्शिता की धारणा है जो इस बात पर जोर देती है कि उनके संदर्भों के संदर्भों को बदलकर सब कुछ संरक्षित है)। इस प्रकार, मुझे लगता है कि आपका प्रश्न बीमार है।
जे। अब्राहमसन

78
  • पूर्ण प्रकार का इंजेक्शन। आप वास्तव में जटिल प्रकार का उपयोग कर सकते हैं जैसे बिना महसूस किए, "पवित्र बकवास, सब मैं कभी लिखता हूं टाइप हस्ताक्षर।"
  • प्रकार पूरी तरह से बीजगणितीय हैं , जो कुछ जटिल विचारों को व्यक्त करना बहुत आसान बनाता है।
  • हास्केल में टाइप कक्षाएं होती हैं, जो एक तरह के इंटरफेस की तरह होती हैं, सिवाय इसके कि आपको एक ही स्थान पर एक प्रकार के लिए सभी कार्यान्वयन नहीं करना पड़ता है। आप मौजूदा तृतीय-पक्ष प्रकारों के लिए अपने स्वयं के प्रकार वर्गों के कार्यान्वयन बना सकते हैं, उनके स्रोत तक पहुंच की आवश्यकता के बिना।
  • उच्च-क्रम और पुनरावर्ती कार्यों में टाइप परीक्षक के दायरे में अधिक कार्यक्षमता डालने की प्रवृत्ति होती है। उदाहरण के लिए, फ़िल्टर लें । एक अनिवार्य भाषा में, आप एक forही कार्यक्षमता को लागू करने के लिए एक लूप लिख सकते हैं , लेकिन आपके पास एक ही स्थिर प्रकार की गारंटी नहीं होगी, क्योंकि forलूप में रिटर्न प्रकार की कोई अवधारणा नहीं है।
  • उपप्रकारों की कमी पैरामीट्रिक बहुरूपता को सरल बनाती है।
  • हस्केल में उच्च-प्रकार के प्रकार (प्रकार के प्रकार) निर्दिष्ट करना और उपयोग करना अपेक्षाकृत आसान है, जो आपको उन प्रकारों के बारे में सार बनाने की अनुमति देता है जो जावा में पूरी तरह से अथाह हैं।

7
अच्छा जवाब - क्या आप मुझे एक उच्च दयालु प्रकार का एक सरल उदाहरण दे सकते हैं, सोचें कि मुझे यह समझने में मदद मिलेगी कि जावा में ऐसा करना असंभव क्यों है।
फतमानस

3
यहाँ कुछ अच्छे उदाहरण हैं
कार्ल बेवेलफेल्ट

3
पैटर्न मिलान भी वास्तव में महत्वपूर्ण है, इसका मतलब है कि आप निर्णय को आसानी से सुपर बनाने के लिए किसी ऑब्जेक्ट के प्रकार का उपयोग कर सकते हैं।
बेंजामिन ग्रुएनबाम

2
@BenjaminGruenbaum मुझे नहीं लगता कि मैं एक प्रकार की प्रणाली सुविधा कहूंगा।
डोभाल

3
ADTS और HKTs निश्चित रूप से इस सवाल का जवाब मुझे शक है इस सवाल पूछ किसी को पता करने के लिए क्यों वे उपयोगी होते हैं जा रहा है का हिस्सा हैं, वहीं मेरा सुझाव है कि दोनों वर्गों यह समझाने के लिए विस्तारित किया जा करने की जरूरत है
जे।

62
a :: Integer
b :: Maybe Integer
c :: IO Integer
d :: Either String Integer

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

(आप, हालांकि, प्रकार की घोषणाओं को छोड़ सकते हैं। ज्यादातर मामलों में, कंपाइलर आपके चर के लिए सबसे सामान्य प्रकार निर्धारित कर सकता है, जिसके परिणामस्वरूप एक सफल संकलन होगा। क्या यह साफ नहीं है?)


11
+1 मैं इसे बहुत अच्छा प्रश्न के स्तर पर खड़ा किया है लगता है, जबकि इस जवाब पूरा नहीं हुआ है
जे।

1
+1 हालांकि यह समझाने में मदद करेगा कि अन्य भाषाओं में भी है Maybe(जैसे जावा का Optionalऔर स्काला का Option), लेकिन उन भाषाओं में यह एक अर्ध-बेक्ड समाधान है, क्योंकि आप हमेशा nullउस प्रकार के एक चर को असाइन कर सकते हैं , और आपका प्रोग्राम रन-वे पर फट सकता है। समय। हास्केल [1] के साथ ऐसा नहीं हो सकता है, क्योंकि कोई अशक्त मूल्य नहीं है , इसलिए आप बस धोखा नहीं दे सकते। ([1]: वास्तव में, आप आंशिक फ़ंक्शन का उपयोग करके NullPointerException जैसी त्रुटि उत्पन्न कर सकते हैं, जैसे कि fromJustजब आपके पास होता है Nothing, लेकिन वे फ़ंक्शन संभवतः पर आधारित होते हैं)।
एंड्रेस एफ।

2
"एक पूर्णांक जिसका मान बाहरी दुनिया से आया है" - IO Integer'सबप्रोग्राम के करीब नहीं होगा , जिसे निष्पादित करते समय पूर्णांक देता है'? पहले के रूप main = c >> cमें मूल्य के रूप में) पहले cसे अलग हो सकता है, फिर दूसरे cसमय aतक इसकी स्थिति की परवाह किए बिना एक ही मूल्य होगा (जब तक हम एकल दायरे में हैं) बी) ऐसे प्रकार हैं जो बाहरी संसार के मूल्यों को निरूपित करने के लिए इसके संन्यास को लागू करते हैं (यानी उन्हें सीधे नहीं बल्कि पहले जांच लें कि उपयोगकर्ता से इनपुट सही है / नहीं दुर्भावनापूर्ण)।
मैकीज पीचोटका

4
Maciej, यह अधिक सटीक होगा। मैं सादगी के लिए प्रयासरत था।
वोल्फफ़ैन

30

बहुत से लोगों ने हास्केल के बारे में अच्छी बातें सूचीबद्ध की हैं। लेकिन आपके विशिष्ट प्रश्न के जवाब में "टाइप सिस्टम प्रोग्राम को अधिक सही क्यों बनाता है?", मुझे संदेह है कि उत्तर "पैरामीट्रिक बहुरूपता" है।

निम्नलिखित हास्केल फ़ंक्शन पर विचार करें:

foobar :: x -> y -> y

नहीं है सचमुच ही एक संभव तरीके से इस समारोह को लागू करने। बस हस्ताक्षर द्वारा, मैं ठीक से बता सकता हूं कि यह फ़ंक्शन क्या करता है, क्योंकि यह केवल एक ही संभव चीज है जो यह कर सकता है। [ठीक है, काफी नहीं, लेकिन लगभग!]

एक पल के लिए रुकिए और सोचिए। यह वास्तव में एक बहुत बड़ी बात है! इसका मतलब है कि अगर मैं इस हस्ताक्षर के साथ एक फ़ंक्शन लिखता हूं, तो फ़ंक्शन के लिए वास्तव में यह असंभव है कि मैं क्या इरादा था। (प्रकार का हस्ताक्षर स्वयं अभी भी गलत हो सकता है, निश्चित रूप से। कोई भी प्रोग्रामिंग भाषा कभी भी सभी बग को नहीं रोकेगी ।)

इस समारोह पर विचार करें:

fubar :: Int -> (x -> y) -> y

यह कार्य असंभव है । आप सचमुच इस फ़ंक्शन को लागू नहीं कर सकते। मैं यह बता सकता हूं कि सिर्फ टाइप सिग्नेचर से।

जैसा कि आप देख सकते हैं, एक हास्केल प्रकार का हस्ताक्षर आपको बहुत नरक बताता है!


C # से तुलना करें। (क्षमा करें, मेरा जावा थोड़ा कठोर है।)

public static TY foobar<TX, TY>(TX in1, TY in2)

इस पद्धति से कुछ चीजें हो सकती हैं:

  • in2परिणाम के रूप में लौटें ।
  • हमेशा के लिए पाश, और कभी भी कुछ भी वापस नहीं।
  • एक अपवाद फेंक दें, और कभी भी कुछ भी वापस न करें।

दरअसल, हास्केल के पास ये तीन विकल्प भी हैं। लेकिन C # आपको अतिरिक्त विकल्प भी देता है:

  • वापसी शून्य। (हास्केल में अशक्त नहीं है।)
  • in2इसे वापस करने से पहले संशोधित करें । (हास्केल में इन-प्लेस संशोधन नहीं है।)
  • प्रतिबिंब का उपयोग करें। (हास्केल में प्रतिबिंब नहीं है।)
  • परिणाम वापस करने से पहले कई I / O क्रियाएं करें। (हास्केल आपको I / O प्रदर्शन करने की अनुमति नहीं देगा जब तक कि आप घोषित नहीं करते कि आप यहाँ I / O करते हैं।)

प्रतिबिंब एक विशेष रूप से बड़ा हथौड़ा है; प्रतिबिंब का उपयोग करके, मैं TYपतली हवा से बाहर एक नई वस्तु का निर्माण कर सकता हूं , और इसे वापस कर सकता हूं ! मैं दोनों वस्तुओं का निरीक्षण कर सकता हूं, और जो मुझे मिलता है उसके आधार पर अलग-अलग क्रियाएं कर सकता हूं। में पारित दोनों वस्तुओं के लिए मैं मनमाना संशोधन कर सकता हूँ।

I / O एक समान बड़ा हथौड़ा है। कोड उपयोगकर्ता को संदेश प्रदर्शित कर सकता है, या डेटाबेस कनेक्शन खोल सकता है, या आपकी हार्डडिस्क या कुछ भी सुधार कर सकता है, वास्तव में।


Haskell foobarफ़ंक्शन, इसके विपरीत, केवल कुछ डेटा ले सकता है और उस डेटा को वापस कर सकता है, अपरिवर्तित। यह डेटा को "नहीं" देख सकता है, क्योंकि इसका प्रकार संकलन-समय पर अज्ञात है। यह नया डेटा नहीं बना सकता, क्योंकि ... ठीक है, आप किसी भी संभावित प्रकार के डेटा का निर्माण कैसे करते हैं? आपको इसके लिए प्रतिबिंब की आवश्यकता होगी। यह किसी भी I / O का प्रदर्शन नहीं कर सकता है, क्योंकि टाइप हस्ताक्षर यह घोषित नहीं करता है कि I / O का प्रदर्शन किया जा रहा है। तो यह फाइलसिस्टम या नेटवर्क के साथ बातचीत नहीं कर सकता है, या यहां तक ​​कि एक ही प्रोग्राम में थ्रेड चल रहा है! (यानी, यह 100% गारंटीकृत धागा-सुरक्षित है।)

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

(स्पष्ट होना: यह अभी भी संभव है कि हास्केल फ़ंक्शंस लिखना संभव नहीं है, जहां टाइप सिग्नेचर आपको ज़्यादा नहीं बताता। Int -> Intबस कुछ भी हो सकता है। लेकिन फिर भी, हम जानते हैं कि एक ही इनपुट हमेशा 100% निश्चितता के साथ एक ही आउटपुट का उत्पादन करेगा। जावा भी इसकी गारंटी नहीं देता है! '


4
+1 शानदार जवाब! यह बहुत शक्तिशाली है और अक्सर नए लोगों द्वारा हास्केल को कम आंका जाता है। वैसे, एक सरल "असंभव" फ़ंक्शन होगा fubar :: a -> b, है ना? (हाँ, मुझे पता है unsafeCoerce। मुझे लगता है कि हम इसके नाम पर "असुरक्षित" के साथ कुछ भी नहीं बोल रहे हैं, और न ही नए लोगों को इसके बारे में चिंता करनी चाहिए !: डी)
एंड्रेस एफ।

बहुत सारे सरल प्रकार के हस्ताक्षर हैं जो आप नहीं लिख सकते, हाँ। उदाहरण के लिए, foobar :: xबहुत अकल्पनीय है ...
मैथमेटिकलऑर्चिड

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

अधिक पेशेवर रूप से आप इन विधियों को in1 या in2 पर कॉल कर सकते हैं जिनके दुष्प्रभाव हैं। या आप वैश्विक स्थिति को संशोधित कर सकते हैं (जो दी गई है, हास्केल में एक IO कार्रवाई के रूप में मॉडलिंग की गई है, लेकिन ऐसा नहीं हो सकता है जो ज्यादातर लोग IO के रूप में सोचते हैं)।
डग मैकक्लीन

2
@isomorphismes प्रकार x -> y -> yपूरी तरह से कार्यान्वयन योग्य है। प्रकार (x -> y) -> yनहीं है। प्रकार x -> y -> yदो इनपुट लेता है, और दूसरा लौटाता है। प्रकार (x -> y) -> yलेता है एक समारोह है कि पर चल रही है x, और किसी भी तरह एक बनाने के लिए है yकि से बाहर ...
MathematicalOrchid

17

एक संबंधित एसओ प्रश्न

मुझे लगता है कि आप हैस्केल में ऐसा कर सकते हैं (यानी सामान / सामान में चीजें जो वास्तव में प्रथम श्रेणी के डेटापेट होनी चाहिए)

नहीं, आप वास्तव में नहीं कर सकते हैं - कम से कम उसी तरह से नहीं जैसे कि जावा कर सकता है। जावा में, इस तरह की बात होती है:

String x = (String)someNonString;

और जावा खुशी से आपके गैर-स्ट्रिंग को स्ट्रिंग के रूप में आज़माएगा। हास्केल इस तरह की बात की अनुमति नहीं देता है, रनटाइम त्रुटियों की एक पूरी कक्षा को समाप्त कर देता है।

nullप्रकार प्रणाली का एक हिस्सा है ( Nothingइसलिए) रनटाइम त्रुटियों के एक पूरे अन्य वर्ग को समाप्त करने के लिए स्पष्ट रूप से पूछा और संभाला जाना चाहिए।

अन्य सूक्ष्म लाभों का एक गुच्छा भी है - विशेष रूप से पुन: उपयोग और टाइप-क्लास के आसपास - कि मेरे पास संचार को अच्छी तरह से जानने के लिए विशेषज्ञता नहीं है।

ज्यादातर हालांकि, यह इसलिए है क्योंकि हास्केल का प्रकार सिस्टम बहुत अधिक अभिव्यक्तता की अनुमति देता है। आप केवल कुछ नियमों के साथ बहुत सारी चीजें कर सकते हैं। कभी मौजूद हास्केल पेड़ पर विचार करें:

data Tree a = Leaf a | Branch (Tree a) (Tree a) 

आपने कोड के काफी पठनीय एक लाइन में एक पूरे सामान्य बाइनरी ट्री (और दो डेटा कंस्ट्रक्टर) को परिभाषित किया है। सभी बस कुछ नियमों ( राशि प्रकार और उत्पाद प्रकार वाले ) का उपयोग कर रहे हैं। यह जावा में 3-4 कोड फाइलें और कक्षाएं हैं।

विशेष रूप से उन प्रकारों में जो श्रद्धा प्रकार के सिस्टम हैं, इस प्रकार की संक्षिप्तता / लालित्य अत्यधिक मूल्यवान है।


मैं आपके जवाब से केवल NullPointerException समझ गया। क्या आप और उदाहरण शामिल कर सकते हैं?
जेसविन जोस

2
जरूरी नहीं कि सही हो, JLS §5.5.1 : यदि T एक वर्ग प्रकार है, तो या तो | S | <: | टी | या; टी | <: एस | अन्यथा, एक संकलन-समय त्रुटि उत्पन्न होती है। इसलिए संकलक आपको अनजाने प्रकारों को डालने की अनुमति नहीं देगा - इसके आसपास स्पष्ट रूप से तरीके हैं।
बोरिस द स्पाइडर

मेरी राय में टाइप क्लास के फायदों को डालने का सबसे सरल तरीका यह है कि वे interfaceएस की तरह हैं जिन्हें बाद में जोड़ा जा सकता है, और वे उस प्रकार को नहीं भूलते हैं जो उन्हें लागू कर रहा है। यही है, आप यह सुनिश्चित कर सकते हैं कि फ़ंक्शन के दो तर्क एक ही प्रकार के हैं, एस के विपरीत interfaceजहां दो List<String>एस में अलग-अलग कार्यान्वयन हो सकते हैं। आप प्रत्येक इंटरफ़ेस में एक प्रकार का पैरामीटर जोड़कर तकनीकी रूप से जावा में कुछ समान कर सकते हैं, लेकिन 99% मौजूदा इंटरफेस ऐसा नहीं करते हैं और आप अपने साथियों से नरक को भ्रमित करेंगे।
डोभाल

2
@BoristheSpider सच है, लेकिन कास्टिंग अपवाद लगभग हमेशा एक सुपरक्लास से एक उपवर्ग में या एक इंटरफ़ेस से एक वर्ग तक डाउनकास्टिंग में शामिल होता है, और सुपरक्लास के लिए यह असामान्य नहीं है Object
डोभाल

2
मुझे लगता है कि तार के बारे में प्रश्न में बिंदु कास्टिंग और रनटाइम प्रकार त्रुटियों के साथ नहीं है, लेकिन यह तथ्य कि यदि आप प्रकारों का उपयोग नहीं करना चाहते हैं , तो जावा आपको नहीं बनाएगा - जैसा कि वास्तव में, क्रमबद्ध रूप से आपके डेटा को संग्रहीत करना है। फार्म, एक एडहॉक anyप्रकार के रूप में स्ट्रिंग्स का दुरुपयोग करना । हास्केल आपको ऐसा करने से नहीं रोकेगा, क्योंकि ... ठीक है, इसमें तार हैं। हास्केल आपको उपकरण दे सकता है, यह आपको जबरन बेवकूफ चीजों को करने से नहीं रोक सकता है यदि आप nullएक नेस्टेड संदर्भ में पुनर्निवेश करने के लिए एक दुभाषिया के पर्याप्त रूप से Greenspunning पर जोर देते हैं । कोई भाषा नहीं कर सकती।
लेउशेंको

0

एक 'मेम' जो इससे परिचित लोगों ने अक्सर बात की है, वह है "संपूर्ण" यदि यह संकलन करता है, तो यह काम करेगा * "बात - जो मुझे लगता है कि टाइप सिस्टम की ताकत से संबंधित है।

यह ज्यादातर छोटे कार्यक्रमों के साथ सच है। हास्केल आपको उन गलतियों को करने से रोकता है जो अन्य भाषाओं में आसान हैं (जैसे कि Int32a Word32और a की तुलना करना और कुछ विस्फोट करना), लेकिन यह आपको सभी गलतियों से नहीं रोकता है।

हास्केल वास्तव में रिफैक्टिंग को बहुत आसान बनाता है। यदि आपका कार्यक्रम पहले ठीक था और यह टाइपकास्ट करता है, तो एक उचित मौका है कि यह मामूली सुधार के बाद भी सही होगा।

मैं यह समझने की कोशिश कर रहा हूं कि वास्तव में हास्केल इस संबंध में अन्य सांख्यिकीय रूप से टाइप की गई भाषाओं से बेहतर क्यों हैं।

हास्केल के प्रकार काफी हल्के होते हैं, ऐसे में नए प्रकारों की घोषणा करना आसान है। यह रस्ट जैसी भाषा के विपरीत है, जहां सब कुछ थोड़ा अधिक बोझिल है।

मेरी धारणा यह है कि यह एक मजबूत प्रकार की प्रणाली से लोगों का मतलब है, लेकिन यह मेरे लिए स्पष्ट नहीं है कि हास्केल बेहतर क्यों है।

हास्केल में सरल योग और उत्पाद प्रकारों से परे कई विशेषताएं हैं; यह सार्वभौमिक रूप से मात्रात्मक है (उदाहरण के लिए id :: a -> a)। आप रिकॉर्ड प्रकार वाले फ़ंक्शन भी बना सकते हैं, जो जावा या जंग जैसी भाषा से काफी अलग है।

जीएचसी अकेले प्रकार के आधार पर कुछ उदाहरणों को भी प्राप्त कर सकता है, और जेनरिक के आगमन के बाद से, आप उन कार्यों को लिख सकते हैं जो प्रकारों में सामान्य हैं। यह काफी सुविधाजनक है, और यह जावा की तुलना में अधिक धाराप्रवाह है।

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

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

एक और तरीका रखो, आप अच्छे या बुरे जावा लिख ​​सकते हैं, मुझे लगता है कि आप हास्केल में भी ऐसा कर सकते हैं

यह शायद सच है, लेकिन यह एक महत्वपूर्ण बिंदु याद आ रहा है: वह बिंदु जहां आप हास्केल में अपने आप को पैर में गोली मारना शुरू करते हैं, उस बिंदु से आगे है जब आप अपने आप को जावा में पैर में शूट करना शुरू करते हैं।

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