हास्केल के लिए नए लोगों द्वारा देखा गया सबसे स्पष्ट नवाचार यह है कि अशुद्ध दुनिया के बीच एक अलगाव है जो बाहरी दुनिया के साथ संचार करने और कम्प्यूटेशन और एल्गोरिदम की शुद्ध दुनिया से संबंधित है। एक लगातार शुरुआत सवाल "मैं कैसे से छुटकारा पा सकते है IO
, यानी, धर्मांतरित IO a
में a
?" इसका तरीका यह है कि कोड लिखने के लिए मठों (या अन्य अमूर्तनों) का उपयोग किया जाता है जो आईओ और चेन प्रभाव करता है। यह कोड बाहरी दुनिया से डेटा इकट्ठा करता है, इसका एक मॉडल बनाता है, कुछ संगणना करता है, संभवतः शुद्ध कोड को नियोजित करके, और परिणाम को आउटपुट करता है।
जहां तक उपरोक्त मॉडल का संबंध है, मुझे मोनाड में GUIs में हेरफेर करने के साथ कुछ भी गलत नहीं दिखता है IO
। इस शैली से उत्पन्न सबसे बड़ी समस्या यह है कि मॉड्यूल अब रचना करने योग्य नहीं हैं, यानी, मैं अपने कार्यक्रम में वैश्विक निष्पादन आदेश के बारे में अपना अधिकांश ज्ञान खो देता हूं। इसे ठीक करने के लिए, मुझे समवर्ती, अनिवार्य जीयूआई कोड के समान तर्क लागू करना होगा। इस बीच, अशुद्ध के लिए, गैर-जीयूआई कोड निष्पादन आदेश स्पष्ट है क्योंकि IO
मोनड के >==
ऑपरेटर की परिभाषा (कम से कम जब तक केवल एक धागा है)। शुद्ध कोड के लिए, यह बिल्कुल भी मायने नहीं रखता है, सिवाय इसके कि कोने के मामलों में प्रदर्शन को बढ़ाया जा सके या इसके परिणामस्वरूप मूल्यांकन से बचा जा सके ⊥
।
कंसोल और ग्राफिकल IO के बीच सबसे बड़ा दार्शनिक अंतर यह है कि पूर्व को लागू करने वाले प्रोग्राम आमतौर पर सिंक्रोनस शैली में लिखे जाते हैं। यह संभव है क्योंकि वहाँ (एक तरफ संकेतों और अन्य खुले फ़ाइल विवरणों को छोड़कर) घटनाओं का सिर्फ एक स्रोत है: बाइट स्ट्रीम जिसे आमतौर पर कहा जाता है stdin
। जीयूआई स्वाभाविक रूप से अतुल्यकालिक हैं, और कीबोर्ड की घटनाओं और माउस क्लिक पर प्रतिक्रिया करना है।
कार्यात्मक तरीके से अतुल्यकालिक IO करने के एक लोकप्रिय दर्शन को कार्यात्मक प्रतिक्रियाशील प्रोग्रामिंग (FRP) कहा जाता है। इसने हाल ही में अशुद्ध, गैर-कार्यात्मक भाषाओं के लिए बहुत अधिक कर्षण प्राप्त किया, जो कि रिएक्टिवएक्स जैसे पुस्तकालयों और एल्म जैसी रूपरेखाओं के लिए धन्यवाद । संक्षेप में, यह GUI तत्वों और अन्य चीजों (जैसे कि फ़ाइलें, घड़ियां, अलार्म, कीबोर्ड, माउस) को इवेंट स्रोतों के रूप में देखने के समान है, जिन्हें "वेधशाला" कहा जाता है, जो घटनाओं की धाराओं का उत्सर्जन करते हैं। इन घटनाओं परिचित ऑपरेटर्स का उपयोग इस तरह के रूप संयोजित किया जाता है map
, foldl
, zip
, filter
, concat
, join
, आदि, नई धाराओं का उत्पादन करने के लिए। यह उपयोगी है क्योंकि कार्यक्रम राज्य को कार्यक्रम के रूप scanl . map reactToEvents $ zipN <eventStreams>
में देखा जा सकता है , जहांN
कार्यक्रम द्वारा कभी देखे गए पर्यवेक्षकों की संख्या के बराबर है।
एफआरपी वेधशालाओं के साथ काम करने से कंपोजिटिबिलिटी को पुनर्प्राप्त करना संभव हो जाता है क्योंकि एक स्ट्रीम में घटनाओं को समय पर आदेश दिया जाता है। कारण यह है कि इवेंट स्ट्रीम एब्स्ट्रैक्शन सभी वेधशालाओं को ब्लैक बॉक्स के रूप में देखना संभव बनाता है। अंततः, ऑपरेटरों के उपयोग से इवेंट स्ट्रीम का संयोजन निष्पादन पर कुछ स्थानीय ऑर्डर वापस देता है। यह मुझे और अधिक ईमानदार होने के लिए मजबूर करता है जिसके बारे में मेरा प्रोग्राम वास्तव में निर्भर करता है, उसी तरह से जैसे हास्केल में सभी कार्यों को संदर्भित रूप से पारदर्शी होना चाहिए: यदि मैं अपने कार्यक्रम के दूसरे हिस्से से डेटा खींचना चाहता हूं, तो मुझे स्पष्ट होना होगा विज्ञापन मेरे कार्यों के लिए एक उपयुक्त प्रकार घोषित करते हैं। (IO मोनाद, अशुद्ध कोड लिखने के लिए एक डोमेन-विशिष्ट भाषा होने के नाते, प्रभावी रूप से इसको दरकिनार करता है)