यह IO
भिक्षु की एक सुझाई गई "व्याख्या" है । यदि आप इस "व्याख्या" को गंभीरता से लेना चाहते हैं, तो आपको "रियलवर्ल्ड" को गंभीरता से लेने की आवश्यकता है। यह अप्रासंगिक है कि action world
सट्टा का मूल्यांकन किया जाता है या नहीं, action
इसका कोई साइड-इफेक्ट नहीं है, इसके प्रभाव, यदि कोई हैं, तो ब्रह्मांड के एक नए राज्य को वापस करने के द्वारा नियंत्रित किया जाता है जहां उन प्रभावों को हुआ है, जैसे कि एक नेटवर्क पैकेट भेजा गया है। हालांकि, फ़ंक्शन का परिणाम है ((),world)
और इसलिए ब्रह्मांड की नई स्थिति है world
। हम नए ब्रह्माण्ड का उपयोग नहीं करते हैं जो हमारे पास सटिक रूप से पक्ष में मूल्यांकन किया जा सकता है। ब्रह्मांड की स्थिति है world
।
आपको शायद उस समय को गंभीरता से लेना चाहिए। ऐसे कई तरीके हैं जो सर्वोत्तम सतही विरोधाभासी और निरर्थक हैं। इस दृष्टिकोण के साथ विशेष रूप से गैर-स्पष्ट या पागल है।
"रुको, रुको," आप कहते हैं। " RealWorld
सिर्फ एक 'टोकन' है। यह वास्तव में पूरे ब्रह्मांड की स्थिति नहीं है।" ठीक है, फिर यह "व्याख्या" कुछ भी नहीं समझाती है। फिर भी, एक कार्यान्वयन विवरण के रूप में , यह जीएचसी मॉडल कैसे है IO
। 1 हालांकि, इसका मतलब है कि हमारे पास जादुई "कार्य" हैं जो वास्तव में दुष्प्रभाव हैं और यह मॉडल उनके अर्थ के लिए कोई मार्गदर्शन प्रदान नहीं करता है। और, चूंकि इन कार्यों के वास्तव में दुष्प्रभाव हैं, आप जो चिंता उठाते हैं वह पूरी तरह से बिंदु पर है। GHC है अपने रास्ते से हट जाने के लिए सुनिश्चित करने के लिए है RealWorld
और इन विशेष कार्य तरीके कि कार्यक्रम का इरादा व्यवहार को बदलने में अनुकूलित नहीं कर रहे हैं।
व्यक्तिगत रूप से (जैसा कि शायद अब तक स्पष्ट है), मुझे लगता है कि यह "विश्व-पासिंग" मॉडल IO
सिर्फ बेकार है और एक शैक्षणिक उपकरण के रूप में भ्रमित है। (क्या यह कार्यान्वयन के लिए उपयोगी है, मुझे नहीं पता। जीएचसी के लिए, मुझे लगता है कि यह एक ऐतिहासिक कलाकृतियों से अधिक है।)
एक वैकल्पिक दृष्टिकोण IO
प्रतिक्रिया हैंडलर के साथ एक वर्णन अनुरोध के रूप में देखना है । इसे करने के कई तरीके हैं। संभवतः सबसे सुलभ एक मुक्त मोनाद निर्माण का उपयोग करना है, विशेष रूप से हम उपयोग कर सकते हैं:
data IO a = Return a | Request OSRequest (OSResponse -> IO a)
इसे और अधिक परिष्कृत बनाने के कई तरीके हैं और कुछ बेहतर गुण हैं, लेकिन यह पहले से ही एक सुधार है। इसे समझने के लिए वास्तविकता की प्रकृति के बारे में गहरी दार्शनिक मान्यताओं की आवश्यकता नहीं है। यह सब बताता है कि IO
या तो एक तुच्छ कार्यक्रम है Return
जो कुछ भी नहीं करता है लेकिन एक मूल्य वापस करता है, या यह प्रतिक्रिया के लिए एक हैंडलर के साथ ऑपरेटिंग सिस्टम के लिए एक अनुरोध है। OSRequest
कुछ इस तरह हो सकता है:
data OSRequest = OpenFile FilePath | PutStr String | ...
इसी तरह, OSResponse
कुछ इस तरह हो सकता है:
data OSResponse = Errno Int | OpenSucceeded Handle | ...
(जो सुधार किए जा सकते हैं उनमें से एक है चीजों को और अधिक सुरक्षित बनाना ताकि आप जानते हैं कि आप अनुरोध OpenSucceeded
से नहीं मिलेंगे PutStr
।) यह मॉडल IO
अनुरोधों का वर्णन करने के लिए है जो किसी प्रणाली द्वारा व्याख्या की जाती हैं ("असली" IO
इस के लिए। हास्केल रनटाइम खुद), और फिर, शायद, वह सिस्टम उस हैंडलर को कहेगा जिसे हमने प्रतिक्रिया के साथ प्रदान किया है। यह, ज़ाहिर है, यह भी कोई संकेत नहीं देता है कि अनुरोध को कैसे PutStr "hello world"
संभाला जाना चाहिए, लेकिन यह भी ढोंग नहीं करता है। यह स्पष्ट करता है कि यह किसी अन्य प्रणाली को सौंपा जा रहा है। यह मॉडल भी बहुत सटीक है। आधुनिक OSes में सभी उपयोगकर्ता कार्यक्रमों को कुछ भी करने के लिए OS से अनुरोध करने की आवश्यकता होती है।
यह मॉडल सही अंतर्ज्ञान प्रदान करता है। उदाहरण के लिए, कई शुरुआती लोग <-
ऑपरेटर की तरह चीजों को "अलिखित" के रूप में देखते हैं IO
, या (दुर्भाग्य से प्रबलित) यह मानते हैं कि IO String
ए, कहते हैं, एक "कंटेनर" है जिसमें " String
एस " होता है (और फिर <-
उन्हें बाहर निकालता है)। यह अनुरोध-प्रतिक्रिया दृश्य इस परिप्रेक्ष्य को स्पष्ट रूप से गलत बनाता है। अंदर कोई फ़ाइल हैंडल नहीं है OpenFile "foo" (\r -> ...)
। इस पर जोर देने के लिए एक सामान्य सादृश्य यह है कि केक के लिए एक नुस्खा के अंदर कोई केक नहीं है (या शायद "चालान" इस मामले में बेहतर होगा)।
यह मॉडल संक्षिप्तता के साथ आसानी से काम करता है। हमारे पास आसानी से OSRequest
जैसे के लिए एक कंस्ट्रक्टर हो सकता है Fork :: (OSResponse -> IO ()) -> OSRequest
और फिर रनटाइम इस अतिरिक्त हैंडलर द्वारा उत्पादित अनुरोधों को सामान्य हैंडलर के साथ इंटरलेव कर सकता है, हालांकि इसे पसंद करता है। कुछ चतुराई के साथ आप इस (या संबंधित तकनीकों) का उपयोग वास्तव में संगोष्ठी जैसी चीजों को सीधे कहने के बजाय "हम ओएस के लिए एक अनुरोध करते हैं और चीजें होती हैं।" यह IOSpec
पुस्तकालय कैसे काम करता है।
1 Hugs ने एक निरंतरता-आधारित कार्यान्वयन का उपयोग किया, IO
जो कि स्पष्ट डेटा प्रकार के बजाय अपारदर्शी कार्यों के साथ मेरे द्वारा वर्णित वर्णन के समान है। एचबीसी ने पुराने अनुरोध-प्रतिक्रिया स्ट्रीम-आधारित IO पर जारी एक निरंतरता-आधारित कार्यान्वयन का भी उपयोग किया। NHC (और इस प्रकार YHC) ने थ्रक्स का उपयोग किया, अर्थात मोटे तौर पर IO a = () -> a
हालांकि ()
इसे बुलाया गया था World
, लेकिन यह राज्य-पासिंग नहीं कर रहा है। जेएचसी और यूएचसी मूल रूप से जीएचसी के समान दृष्टिकोण का उपयोग करते थे।