हास्केल के बारे में क्या उपद्रव है? [बन्द है]


109

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

क्या कोई हास्केल उदाहरण दे सकता है जो यह बताता है कि यह इतना सुरुचिपूर्ण / श्रेष्ठ क्यों है?

जवाबों:


134

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

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


47
यह ध्यान दिया जाना चाहिए कि हास्केल के त्रुटि संदेशों में कमी नहीं है, ghc हैं। हास्केल मानक यह निर्दिष्ट नहीं करता है कि त्रुटि संदेश कैसे किया जाता है।
प्यूयूलज़

मेरे जैसे लोगों के लिए, GHC ग्लासगो हास्केल कम्पाइलर के लिए है। en.wikipedia.org/wiki/Glasgow_Haskell_Compiler
Lorem Ipsum

137

यह वह जगह है उदाहरण है कि मुझे आश्वस्त हास्केल जानने के लिए (और लड़का हूँ मुझे खुशी है कि मैंने किया था)।

-- program to copy a file --
import System.Environment

main = do
         --read command-line arguments
         [file1, file2] <- getArgs

         --copy file contents
         str <- readFile file1
         writeFile file2 str

ठीक है, यह एक छोटा, पठनीय कार्यक्रम है। इस लिहाज से यह C प्रोग्राम से बेहतर है। लेकिन यह एक समान संरचना के साथ एक पायथन कार्यक्रम से इतना अलग (कह) कैसे है?

इसका उत्तर आलसी मूल्यांकन है। अधिकांश भाषाओं (यहां तक ​​कि कुछ कार्यात्मक वाले) में, ऊपर दिए गए एक प्रोग्राम की तरह पूरी फ़ाइल को मेमोरी में लोड किया जाएगा, और फिर एक नए नाम के तहत फिर से लिखा जाएगा।

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

जैसा कि यह है, हास्केल को पता चलता है कि इस writeFileपर निर्भर करता है readFile, और इसलिए इस डेटा पथ को अनुकूलित करने में सक्षम है।

हालांकि परिणाम संकलक-निर्भर होते हैं, जब आप उपरोक्त प्रोग्राम चलाते हैं तो आमतौर पर क्या होता है: यह प्रोग्राम पहली फाइल का एक ब्लॉक (8KB) ​​पढ़ता है, फिर दूसरी फाइल पर लिखता है, फिर पहले से दूसरे ब्लॉक को पढ़ता है। फ़ाइल, और इसे दूसरी फ़ाइल पर लिखता है, और इसी तरह। (इस straceपर चलने की कोशिश करें !)

... जो एक फ़ाइल प्रतिलिपि के कुशल सी कार्यान्वयन क्या होगा की तरह एक बहुत कुछ दिखता है।

तो, हास्केल आपको बहुत अधिक प्रदर्शन का त्याग किए बिना - अक्सर कॉम्पैक्ट, पठनीय कार्यक्रम लिखने देता है।

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

  1. बेहतर कार्यक्रम डिजाइन। कम जटिलता कम तर्क त्रुटियों की ओर जाता है।

  2. कॉम्पैक्ट कोड। बग के लिए बहुत कम लाइनें मौजूद हैं।

  3. संकलित त्रुटियाँ। कीड़े के बहुत सारे अभी मान्य हास्केल नहीं हैं

हास्केल हर किसी के लिए नहीं है। लेकिन सभी को इसे आज़माना चाहिए।


आप वास्तव में 8KB स्थिरांक (या जो कुछ भी है) को कैसे बदलेंगे? क्योंकि मैं शर्त लगा सकता हूँ कि एक हास्केल क्रियान्वयन एक सी संस्करण की तुलना में धीमा होगा अन्यथा, विशेष रूप से
प्रीफ़ेटिंग के

1
@ मेहरदाद आप बफर साइज़ को बदल सकते हैं hSetBuffering handle (BlockBuffering (Just bufferSize))
डेविड

3
यह आश्चर्यजनक है कि इस उत्तर में 116 अपवोट हैं फिर भी इसमें क्या गलत है। यह प्रोग्राम पूरी फाइल को पढ़ेगा, जब तक कि आप आलसी बाइटस्ट्रेट्स (जो आप कर सकते हैं Data.Bytestring.Lazy.readFile) का उपयोग नहीं करते हैं, जिसका हस्केल का आलसी (गैर-सख्त) भाषा होने से कोई लेना-देना नहीं है। मोनाड्स अनुक्रमण कर रहे हैं - इसका अर्थ है "जब आप परिणाम निकालते हैं तो सभी दुष्प्रभाव होते हैं"। "आलसी बाइटस्ट्रिंग" जादू के रूप में: यह खतरनाक है, और आप इसे अन्य भाषाओं में समान या सरल वाक्य रचना के साथ कर सकते हैं।
जो सो

14
उबाऊ पुराने मानक readFileभी उसी तरह आलसी आईओ Data.ByteString.Lazy.readFileकरता है। तो जवाब गलत नहीं है, और यह केवल एक कंपाइलर अनुकूलन नहीं है। वास्तव में, यह हास्केल के लिए कल्पना का हिस्सा है : " readFileफ़ंक्शन एक फ़ाइल को पढ़ता है और फ़ाइल की सामग्री को एक स्ट्रिंग के रूप में लौटाता है। फ़ाइल को आलसी के रूप में, मांग पर, पढ़ा जाता है getContents।"
डैनियल वैगनर

1
मुझे लगता है कि अन्य उत्तर उन चीजों की ओर इशारा करते हैं जो हास्केल के बारे में अधिक विशेष हैं। कई भाषाओं / परिवेशों में धाराएँ हैं, आप नोड में कुछ ऐसा ही कर सकते हैं const fs = require('fs'); const [file1, file2] = process.argv.slice(2); fs.createReadStream(file1).pipe(fs.createWriteStream(file2)):। बैश में भी कुछ ऐसा ही है,:cat $1 > $2
मैक्स हाइबर

64

आप गलत सवाल पूछने की तरह हैं।

हास्केल एक ऐसी भाषा नहीं है जहाँ आप कुछ शांत उदाहरणों को देखते हैं और जाते हैं "अहा, मैं अब देखता हूं, यही अच्छा बनाता है!"

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

  • आलसी मूल्यांकन
  • कोई साइड इफेक्ट नहीं (सब कुछ शुद्ध है, आईओ / आदि मोनड्स के माध्यम से होता है)
  • अविश्वसनीय रूप से अभिव्यंजक स्थिर प्रकार की प्रणाली

साथ ही कुछ अन्य पहलू जो कई मुख्यधारा की भाषाओं से अलग हैं (लेकिन कुछ द्वारा साझा किए गए हैं):

  • कार्यात्मक
  • महत्वपूर्ण व्हाट्सएप
  • टाइप किया हुआ

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


17
मैं आपके पहले वाक्य से असहमत हूं। मैं शुरू में हास्केल कोड के कुछ उदाहरणों से वास्तव में प्रभावित हुआ था और जो मुझे वास्तव में आश्वस्त करता था वह सीखने लायक था। यह लेख था: cs.dartmouth.edu/~doug/powser.html लेकिन निश्चित रूप से, यह एक गणितज्ञ / भौतिक विज्ञानी के लिए दिलचस्प है। एक प्रोग्रामर वास्तविक दुनिया के सामान की तलाश में इस उदाहरण को हास्यास्पद मिलेगा।
राफेल एस। कैल्सवेरीनी

2
@ राफेल: यह सवाल है कि "एक प्रोग्रामर जो वास्तविक दुनिया के सामान की तलाश कर रहा है, उससे प्रभावित होगा"?
जेडी

अच्छा प्रश्न! मैं एक "वास्तविक दुनिया" प्रोग्रामर नहीं हूं इसलिए मुझे नहीं पता कि उन्हें क्या पसंद है। हाहाहा ... मुझे पता है कि भौतिकविदों और गणितज्ञों को क्या पसंद है। : पी
राफेल एस। कैल्सवेरीनी

27

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

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


1
खैर, वहाँ हमेशा और केवल एसटी मठ का उपयोग करने की संभावना है और / या unsafePerformIOउन लोगों के लिए जो सिर्फ दुनिया को जलते देखना चाहते हैं;)
आरा

22

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

हास्केल आपको किसी भी सामान्य प्रयोजन की भाषा की तुलना में एक तेज, देशी कोड संकलक की तुलना में समानता के लिए अधिक विकल्प देता है। समानांतर शैलियों के लिए इस तरह के समर्थन के साथ वास्तव में कोई प्रतिस्पर्धा नहीं है:

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


"एक तेज, देशी कोड संकलक के साथ"?
JD

मेरा मानना ​​है कि डॉन्स जीएचसीआई का जिक्र कर रहे हैं।
ग्रेगरी हिगले

3
@Jon: shootout.alioth.debian.org/u32/… हस्केल शूटआउट पर बहुत अच्छा करता है, उदाहरण के लिए।
पीकर

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

1
@GregoryHigley GHCI और GHC के बीच अंतर है।
जेरेमी लिस्ट

18

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


18

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

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

c1 `mappend` c2 `mappend` c3

c1वापसी पर और कहाँ LT, EQया GT, c1लौटने EQसे अभिव्यक्ति का मूल्यांकन, मूल्यांकन जारी रखने का कारण बनता है c2; यदि c2रिटर्न LTया GTयह पूरे का मूल्य है, औरc3 मूल्यांकन नहीं किया गया है। इस तरह की चीज़ बहुत अधिक परिष्कृत और जटिल हो जाती है जैसे मैंडिक मैसेज जनरेटर और पार्सर्स, जहाँ मैं विभिन्न प्रकार के राज्य ले जा सकता हूँ, अलग-अलग गर्भपात की स्थिति होती है, या किसी विशेष कॉल के लिए निर्णय लेने में सक्षम हो सकता है कि क्या वास्तव में गर्भपात का मतलब है "आगे की प्रक्रिया नहीं है" या इसका मतलब है, "अंत में एक त्रुटि लौटाएं, लेकिन आगे के त्रुटि संदेश एकत्र करने के लिए प्रसंस्करण जारी रखें।"

यह सब सामान है जिसमें कुछ समय लगता है और शायद सीखने के लिए काफी कुछ प्रयास करना पड़ता है, और इस प्रकार यह उन लोगों के लिए एक ठोस तर्क बनाना कठिन हो सकता है जो पहले से इन तकनीकों को नहीं जानते हैं। मुझे लगता है कि ऑल अबाउट मोनड्स ट्यूटोरियल इस के एक पहलू का बहुत प्रभावशाली प्रदर्शन करता है, लेकिन मैं यह उम्मीद नहीं करूंगा कि कोई भी पहले से मौजूद सामग्री से परिचित नहीं है या पहले, या तीसरे, सावधान पढ़ने पर "मिलेगा"।

वैसे भी, हास्केल में बहुत सारे अन्य अच्छे सामान हैं, लेकिन यह एक प्रमुख है जिसे मैंने इतनी बार उल्लेख नहीं किया है, शायद इसलिए कि यह बहुत जटिल है।


2
बहुत ही रोचक! हास्केल कोड की कितनी लाइनें आपके स्वचालित व्यापार प्रणाली में कुल मिलाकर चली गईं? आपने गलती को कैसे सहन किया और आपको किस तरह के प्रदर्शन के परिणाम मिले? मैं हाल ही में सोच रहा था कि हास्केल में कम विलंबता प्रोग्रामिंग के लिए अच्छा होने की क्षमता है ...
JD

12

एक दिलचस्प उदाहरण के लिए आप यहां देख सकते हैं: http://en.literateprograms.org/Quicksort_(Haskell)

विभिन्न भाषाओं में कार्यान्वयन को देखने के लिए क्या दिलचस्प है।

हास्केल क्या दिलचस्प बनाता है, अन्य कार्यात्मक भाषाओं के साथ, यह तथ्य है कि आपको प्रोग्राम कैसे करना है, इसके बारे में अलग तरह से सोचना होगा। उदाहरण के लिए, आप आमतौर पर छोरों के लिए या उसके बाद का उपयोग नहीं करेंगे, लेकिन पुनरावृत्ति का उपयोग करेंगे।

जैसा कि ऊपर उल्लेख किया गया है, हास्केल और अन्य कार्यात्मक भाषाएं मल्टी-कोर पर काम करने के लिए समानांतर प्रसंस्करण और लेखन अनुप्रयोगों के साथ उत्कृष्ट हैं।


2
पुनरावृत्ति बम है। कि और पैटर्न मिलान।
एलेरी न्यूकमर

1
कार्यात्मक भाषा में लिखते समय मेरे लिए सबसे कठिन हिस्सा है जबकि छोरों से छुटकारा पाना। :)
जेम्स ब्लैक

4
लूप के बजाय पुनरावृत्ति में सोचना सीखना मेरे लिए सबसे कठिन हिस्सा था। जब यह अंत में डूब गया, तो यह मेरे द्वारा अब तक की गई सबसे बड़ी प्रोग्रामिंग एपिफेनी में से एक थी।
क्रिस कॉन्नेट

8
सिवाय इसके कि हास्केल प्रोग्रामर शायद ही कभी आदिम पुनरावृत्ति का उपयोग करता है; ज्यादातर आप नक्शे और तह जैसे पुस्तकालय कार्यों का उपयोग करते हैं।
पॉल जॉनसन

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

8

मैं आपको एक उदाहरण नहीं दे सकता, मैं एक OCaml लड़का हूं, लेकिन जब मैं खुद के साथ ऐसी स्थिति में हूं, तो जिज्ञासा बस पकड़ लेती है और मुझे एक कंपाइलर / दुभाषिया डाउनलोड करना पड़ता है और इसे देना पड़ता है। आप संभवतः किसी दिए गए कार्यात्मक भाषा की ताकत और कमजोरियों के बारे में और अधिक सीखेंगे।


1
कंपाइलर के सोर्स कोड को पढ़ना न भूलें। इससे आपको बहुत सी मूल्यवान जानकारी भी मिलेगी।
जेडी

7

एल्गोरिदम या गणितीय समस्याओं से निपटने के दौरान एक बात मुझे बहुत अच्छी लगती है कि हास्केल की गणनाओं का अंतर्निहित आलसी मूल्यांकन है, जो केवल इसकी सख्त कार्यात्मक प्रकृति के कारण ही संभव है।

उदाहरण के लिए, यदि आप सभी primes की गणना करना चाहते हैं, तो आप उपयोग कर सकते हैं

primes = sieve [2..]
    where sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0]

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

foo = sum $ takeWhile (<100) primes

जो सभी 100 से कम primes गाया जाता है। यह कई कारणों से अच्छा है। सबसे पहले, मुझे केवल एक ही प्राइम फंक्शन लिखना होगा जो सभी प्राइम्स को जनरेट करता है और फिर मैं प्राइम्स के साथ काम करने के लिए बहुत ज्यादा तैयार हूं। ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग भाषा में, मुझे फ़ंक्शन को यह बताने के लिए किसी तरह की आवश्यकता होगी कि लौटने से पहले कितने प्राइम की गणना करनी चाहिए या किसी वस्तु के साथ अनंत सूची व्यवहार का अनुकरण करना चाहिए। एक और बात यह है कि सामान्य तौर पर, आप लेखन कोड को समाप्त करते हैं जो व्यक्त करता है कि आप क्या गणना करना चाहते हैं और किन चीजों का मूल्यांकन करने के लिए नहीं - इसके बजाय संकलक आपके लिए ऐसा करता है।

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


2
यह पूरी तरह सच नहीं है; C # (एक ऑब्जेक्ट-ओरिएंटेड भाषा) के यील्ड रिटर्न व्यवहार के साथ, आप अनंत सूचियों की भी घोषणा कर सकते हैं जिनका मांग पर मूल्यांकन किया जाता है।
जेफ येट्स

2
अच्छी बात। आप सही हैं और मुझे यह बताने से बचना चाहिए कि क्या अन्य भाषाओं में ऐसा नहीं किया जा सकता है। मुझे लगता है कि मेरा उदाहरण त्रुटिपूर्ण था, लेकिन मुझे अभी भी लगता है कि आप हास्केल के आलसी मूल्यांकन के तरीके से कुछ हासिल करते हैं: यह वास्तव में डिफ़ॉल्ट रूप से और प्रोग्रामर के किसी भी प्रयास के बिना है। और यह, मेरा मानना ​​है, इसकी कार्यात्मक प्रकृति और दुष्प्रभावों की अनुपस्थिति के कारण है।
वैक्सिंग

8
आपको यह पढ़ने में दिलचस्पी हो सकती है कि "छलनी" एराटोस्थनीज की छलनी क्यों नहीं है: lambda-the-ultimate.org/node/3127
क्रिस कॉनवे

@ क्रिस: धन्यवाद, यह वास्तव में एक बहुत ही दिलचस्प लेख था! उपरोक्त primes फंक्शन वह नहीं है जिसका उपयोग मैं अपनी गणना के लिए कर रहा हूँ क्योंकि यह दर्द से धीमा है। फिर भी, लेख एक अच्छा बिंदु लाता है जो मॉड के लिए सभी नंबरों की जांच करना वास्तव में एक अलग एल्गोरिथ्म है।
वैक्सिंग

6

मैं दूसरों से सहमत हूं कि कुछ छोटे उदाहरणों को देखना हास्केल को दिखाने का सबसे अच्छा तरीका नहीं है। लेकिन मैं कुछ भी दे दूँगा। यहां यूलर प्रोजेक्ट की समस्याओं का हल 18 और 67 में दिया गया है , जो आपको एक त्रिकोण के शीर्ष पर आधार से अधिकतम-राशि का रास्ता खोजने के लिए कहता है:

bottomUp :: (Ord a, Num a) => [[a]] -> a
bottomUp = head . bu
  where bu [bottom]     = bottom
        bu (row : base) = merge row $ bu base
        merge [] [_] = []
        merge (x:xs) (y1:y2:ys) = x + max y1 y2 : merge xs (y2:ys)

यहाँ Lesh और Mitzenmacher द्वारा बुलबुला खोज एल्गोरिथ्म का एक पूर्ण, पुन: प्रयोज्य कार्यान्वयन है । मैंने इसका उपयोग डीवीडी पर संग्रहणीय संग्रहण के लिए बड़ी मीडिया फ़ाइलों को बिना कचरे के पैक करने के लिए किया:

data BubbleResult i o = BubbleResult { bestResult :: o
                                     , result :: o
                                     , leftoverRandoms :: [Double]
                                     }
bubbleSearch :: (Ord result) =>
                ([a] -> result) ->       -- greedy search algorithm
                Double ->                -- probability
                [a] ->                   -- list of items to be searched
                [Double] ->              -- list of random numbers
                [BubbleResult a result]  -- monotone list of results
bubbleSearch search p startOrder rs = bubble startOrder rs
    where bubble order rs = BubbleResult answer answer rs : walk tries
            where answer = search order
                  tries  = perturbations p order rs
                  walk ((order, rs) : rest) =
                      if result > answer then bubble order rs
                      else BubbleResult answer result rs : walk rest
                    where result = search order

perturbations :: Double -> [a] -> [Double] -> [([a], [Double])]
perturbations p xs rs = xr' : perturbations p xs (snd xr')
    where xr' = perturb xs rs
          perturb :: [a] -> [Double] -> ([a], [Double])
          perturb xs rs = shift_all p [] xs rs

shift_all p new' [] rs = (reverse new', rs)
shift_all p new' old rs = shift_one new' old rs (shift_all p)
  where shift_one :: [a] -> [a] -> [Double] -> ([a]->[a]->[Double]->b) -> b
        shift_one new' xs rs k = shift new' [] xs rs
          where shift new' prev' [x] rs = k (x:new') (reverse prev') rs
                shift new' prev' (x:xs) (r:rs) 
                    | r <= p    = k (x:new') (prev' `revApp` xs) rs
                    | otherwise = shift new' (x:prev') xs rs
                revApp xs ys = foldl (flip (:)) ys xs

मुझे यकीन है कि यह कोड रैंडम जिबरिश जैसा दिखता है। लेकिन अगर आप मिटज़ेनमाकर के ब्लॉग प्रविष्टि को पढ़ते हैं और एल्गोरिदम को समझते हैं, तो आप आश्चर्यचकित होंगे कि एल्गोरिथ्म को कोड में पैकेज करना संभव है, इसके बारे में कुछ भी कहे बिना आप जो खोज रहे हैं।

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


5

मेरे लिए, हास्केल का आकर्षण संकलक गारंटी शुद्धता का वादा है । भले ही यह कोड के शुद्ध भागों के लिए हो।

मैं वैज्ञानिक सिमुलेशन कोड का एक बहुत कुछ लिखा है, और आश्चर्य होता है इसलिए होगा कि मेरे पहले कोड में एक बग, जो वर्तमान बहुत काम गलत हो सकते हैं था कई बार।


6
यह शुद्धता की गारंटी कैसे देता है?
जोनाथन Fischoff 17

कोड के शुद्ध भाग अशुद्ध लोगों की तुलना में अधिक सुरक्षित हैं। स्तर के विश्वास / प्रयास-निवेश का तरीका अधिक है।
आरपीजी

1
आपने उसे क्या छाप दिया?
JD

5

मुझे लगता है कि कुछ कार्यों के लिए मैं हास्केल के साथ अविश्वसनीय रूप से उत्पादक हूं।

इसका कारण सक्सेस सिंटेक्स और परीक्षण में आसानी है।

यह फ़ंक्शन फ़ंक्शन सिंटैक्स की तरह है:

foo a = 5

यह सबसे आसान तरीका है कि मैं एक फ़ंक्शन को परिभाषित करने के बारे में सोच सकता हूं।

अगर मैं उलटा लिखूं

inverseFoo a = a - 5

मैं देख सकता हूँ कि यह किसी भी यादृच्छिक इनपुट के लिए लिखकर उलटा है

prop_IsInverse :: डबल ->
बूल Prop_IsInverse a = a == (inverseFoo $ foo a)

और कमांड लाइन से कॉल करना

jonny @ ubuntu: runhaskell quickCheck + नाम fooFileName.hs

जो यह जांच करेगा कि मेरी फ़ाइल की सभी संपत्तियां बेतरतीब ढंग से इनपुट का परीक्षण करके आयोजित की गई हैं।

मुझे नहीं लगता कि हास्केल हर चीज के लिए सही भाषा है, लेकिन जब छोटे कार्यों और परीक्षण की बात आती है, तो मैंने कुछ भी बेहतर नहीं देखा है। यदि आपके प्रोग्रामिंग में गणितीय घटक है तो यह बहुत महत्वपूर्ण है।


आप किन समस्याओं को हल कर रहे हैं और आपने किन अन्य भाषाओं में प्रयास किया है?
जेडी

1
मोबाइल और iPad के लिए वास्तविक समय 3 डी ग्राफिक्स।
जोनाथन फिशऑफ

3

यदि आप हास्केल में प्रकार प्रणाली के चारों ओर अपना सिर लपेट सकते हैं, तो मुझे लगता है कि अपने आप में एक उपलब्धि है।


1
पाने के लिए क्या है? यदि आपको "डेटा" == "वर्ग" और "टाइपकास्ट" = "इंटरफ़ेस" / "भूमिका" / "विशेषता" के बारे में सोचना चाहिए। यह सरल नहीं हो सकता। (आपको गड़बड़ करने के लिए "अशक्त" भी नहीं है।
अशांति

8
वहाँ एक पूरी बहुत कुछ है, jrockway। जब आप और मैं इसे अपेक्षाकृत सरल पाते हैं, तो कई लोग - यहां तक ​​कि कई डेवलपर्स - कुछ निश्चित प्रकार के सार को समझना बहुत मुश्किल है। मैं कई डेवलपर्स को जानता हूं जो अभी भी अधिक मुख्यधारा की भाषाओं में संकेत और संदर्भ के विचार को समझ नहीं पाते हैं, भले ही वे हर दिन उनका उपयोग करते हैं।
ग्रेगरी हिगले

2

इसका कोई लूप निर्माण नहीं है। कई भाषाओं में यह विशेषता नहीं है।


17
ghci>: m + Control.Monad ghci> forM_ [1..3] प्रिंट 1 2 3
sastanin

1

मैं उन लोगों से सहमत हूं जिन्होंने कहा कि कार्यात्मक प्रोग्रामिंग आपके मस्तिष्क को एक अलग कोण से प्रोग्रामिंग को देखने में मोड़ देता है। मैंने इसे केवल एक शौक़ीन व्यक्ति के रूप में इस्तेमाल किया है, लेकिन मुझे लगता है कि मैंने मूलभूत रूप से एक समस्या का तरीका बदल दिया है। मुझे नहीं लगता कि हास्केल (और पाइथन में सूची बोध का उपयोग करने वाले) का खुलासा किए बिना मैं LINQ के साथ लगभग उतना ही प्रभावी रहा होगा।


-1

एक विरोधाभासी दृष्टिकोण को हवा देने के लिए: स्टीव येजे लिखते हैं कि हिंदुली-मिलनर भाषाओं में अच्छे सिस्टम लिखने के लिए आवश्यक लचीलेपन की कमी है :

एचएम बहुत सुंदर है, पूरी तरह से बेकार औपचारिक गणितीय अर्थ में। यह कुछ गणना का निर्माण बहुत अच्छी तरह से करता है; हास्केल, SML और OCaml में पाया जाने वाला पैटर्न मिलान प्रेषण विशेष रूप से उपयोगी है। अप्रत्याशित रूप से, यह कुछ अन्य सामान्य और अत्यधिक वांछनीय निर्माणों को अजीब रूप से सबसे अच्छे रूप में संभालता है, लेकिन वे उन परिदृश्यों को यह कहकर समझाते हैं कि आप गलत हैं, आप वास्तव में उन्हें नहीं चाहते हैं। तुम्हें पता है, ओह, सेटिंग चर जैसी चीजें।

हास्केल सीखने लायक है, लेकिन इसकी अपनी कमजोरियां हैं।


5
हालांकि यह निश्चित रूप से सच है कि मजबूत प्रकार की प्रणालियों को आम तौर पर आपको उनका पालन करने की आवश्यकता होती है (जो कि उनकी ताकत को उपयोगी बनाता है), यह भी मामला है कि कई (सबसे!) मौजूदा एचएम-आधारित प्रकार की प्रणालियां वास्तव में, किसी प्रकार का है? लिंक के रूप में बच 'हैच' (उदाहरण के रूप में ओ'ज़ामल में ओब्जामैजिक ले लो, हालांकि मैंने इसे हैक के अलावा कभी इस्तेमाल नहीं किया है); व्यवहार में, हालांकि, कई प्रकार के कार्यक्रमों के लिए किसी को भी इस तरह के उपकरण की आवश्यकता नहीं होती है।
जैच स्नो

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

5
-1: स्टीव के बयान आंशिक रूप से पुराने हैं लेकिन ज्यादातर पूरी तरह से तथ्यात्मक रूप से गलत हैं। OCaml का आराम मूल्य प्रतिबंध और .NET का प्रकार प्रणाली उनके बयानों के लिए कुछ स्पष्ट काउंटर उदाहरण हैं।
जद

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

3
यद्यपि मैं स्थिर बनाम गतिशील टाइपिंग पर येजेज से असहमत हूं, हास्केल के पास Data.Dynamic प्रकार है। यदि आप गतिशील टाइपिंग चाहते हैं, तो आप यह कर सकते हैं!
जर्कवे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.