हास्केल में साइड-इफेक्ट्स को मोनाड्स के रूप में क्यों बनाया गया है?


172

क्या कोई इस बात पर कुछ संकेत दे सकता है कि हास्केल में अशुद्ध गणनाओं को मोनाड्स के रूप में क्यों बनाया गया है?

मेरा मतलब है कि मोनाड सिर्फ 4 ऑपरेशन वाला एक इंटरफ़ेस है, इसलिए इसमें मॉडलिंग के साइड-इफेक्ट्स का क्या कारण था?


15
मोनाड्स सिर्फ दो ऑपरेशन को परिभाषित करते हैं।
दारियो

3
लेकिन वापसी और असफल होने के बारे में क्या? (इसके अलावा (>>) और (>> =))
bodacydo

55
दो आपरेशन कर रहे हैं returnऔर (>>=)x >> yके रूप में ही है x >>= \\_ -> y(यानी यह पहले तर्क के परिणाम की उपेक्षा करता है)। हम बात नहीं करते fail
22:30

2
@Porges असफल के बारे में बात क्यों नहीं करते? इसका शायद कुछ हद तक उपयोगी है, शायद, पार्सर, आदि
वैकल्पिक

16
@monadic: एक ऐतिहासिक दुर्घटना के कारण कक्षा failमें है Monad; यह वास्तव में है MonadPlus। ध्यान दें कि इसकी डिफ़ॉल्ट परिभाषा असुरक्षित है।
जेबी

जवाबों:


292

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

तो, एक अशुद्ध कार्य के लिए

f' :: Int -> Int

हम RealWorld को विचार में जोड़ते हैं

f :: Int -> RealWorld -> (Int, RealWorld)
-- input some states of the whole world,
-- modify the whole world because of the side effects,
-- then return the new world.

फिर fसे शुद्ध है। हम एक पैरामीरिज्ड डेटा प्रकार को परिभाषित करते हैं type IO a = RealWorld -> (a, RealWorld), इसलिए हमें कई बार RealWorld टाइप करने की आवश्यकता नहीं है, और बस लिख सकते हैं

f :: Int -> IO Int

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

"अशुद्ध" कार्यों की संरचना

यदि हम उन्हें एक साथ श्रृंखला नहीं दे सकते हैं तो ये अशुद्ध कार्य बेकार हैं। विचार करें

getLine     :: IO String            ~            RealWorld -> (String, RealWorld)
getContents :: String -> IO String  ~  String -> RealWorld -> (String, RealWorld)
putStrLn    :: String -> IO ()      ~  String -> RealWorld -> ((),     RealWorld)

हम चाहते हैं

  • प्राप्त कंसोल से एक फ़ाइल नाम,
  • उस फ़ाइल को पढ़ें , और
  • उस फ़ाइल की सामग्री को कंसोल पर प्रिंट करें

यदि हम वास्तविक विश्व राज्यों तक पहुँच प्राप्त कर सकते हैं तो हम इसे कैसे करेंगे?

printFile :: RealWorld -> ((), RealWorld)
printFile world0 = let (filename, world1) = getLine world0
                       (contents, world2) = (getContents filename) world1 
                   in  (putStrLn contents) world2 -- results in ((), world3)

हम यहां एक पैटर्न देखते हैं। कार्यों को इस तरह कहा जाता है:

...
(<result-of-f>, worldY) = f               worldX
(<result-of-g>, worldZ) = g <result-of-f> worldY
...

इसलिए हम ~~~उन्हें बाँधने के लिए एक ऑपरेटर को परिभाषित कर सकते हैं:

(~~~) :: (IO b) -> (b -> IO c) -> IO c

(~~~) ::      (RealWorld -> (b,   RealWorld))
      ->                    (b -> RealWorld -> (c, RealWorld))
      ->      (RealWorld                    -> (c, RealWorld))
(f ~~~ g) worldX = let (resF, worldY) = f worldX
                   in g resF worldY

तब हम बस लिख सकते थे

printFile = getLine ~~~ getContents ~~~ putStrLn

वास्तविक दुनिया को छुए बिना।

"Impurification"

अब मान लें कि हम फाइल कंटेंट को अपरकेस बनाना चाहते हैं। अपरकेसिंग एक शुद्ध कार्य है

upperCase :: String -> String

लेकिन इसे वास्तविक दुनिया में लाने के लिए, इसे वापस लौटना होगा IO String। इस तरह के समारोह को उठाना आसान है:

impureUpperCase :: String -> RealWorld -> (String, RealWorld)
impureUpperCase str world = (upperCase str, world)

इसे सामान्यीकृत किया जा सकता है:

impurify :: a -> IO a

impurify :: a -> RealWorld -> (a, RealWorld)
impurify a world = (a, world)

ताकि impureUpperCase = impurify . upperCase, और हम लिख सकें

printUpperCaseFile = 
    getLine ~~~ getContents ~~~ (impurify . upperCase) ~~~ putStrLn

(नोट: आम तौर पर हम लिखते हैं getLine ~~~ getContents ~~~ (putStrLn . upperCase))

हम सभी भिक्षुओं के साथ काम कर रहे थे

अब देखते हैं कि हमने क्या किया है:

  1. हमने एक ऑपरेटर को परिभाषित किया है (~~~) :: IO b -> (b -> IO c) -> IO cजो दो अशुद्ध कार्यों को एक साथ जोड़ता है
  2. हमने एक फ़ंक्शन को परिभाषित किया है impurify :: a -> IO aजो अशुद्ध करने के लिए एक शुद्ध मूल्य को परिवर्तित करता है।

अब हम पहचान बनाने (>>=) = (~~~)और return = impurify, और देखते हैं? हमें एक सन्यासी मिला है।


तकनीकी नोट

यह सुनिश्चित करने के लिए कि यह वास्तव में एक सनक है, अभी भी कुछ स्वयंसिद्ध हैं जिन्हें भी जाँचने की आवश्यकता है:

  1. return a >>= f = f a

     impurify a                =  (\world -> (a, world))
    (impurify a ~~~ f) worldX  =  let (resF, worldY) = (\world -> (a, world )) worldX 
                                  in f resF worldY
                               =  let (resF, worldY) =            (a, worldX)       
                                  in f resF worldY
                               =  f a worldX
  2. f >>= return = f

    (f ~~~ impurify) worldX  =  let (resF, worldY) = f worldX 
                                in impurify resF worldY
                             =  let (resF, worldY) = f worldX      
                                in (resF, worldY)
                             =  f worldX
  3. f >>= (\x -> g x >>= h) = (f >>= g) >>= h

    व्यायाम के रूप में छोड़ दिया।


5
+1 लेकिन मैं यह नोट करना चाहता हूं कि यह विशेष रूप से IO केस को कवर करता है। blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html सुंदर समान है, लेकिन सामान्यीकरण RealWorldमें ... ठीक है, आप देखेंगे।
युगांतरकारी

4
ध्यान दें कि यह स्पष्टीकरण वास्तव में हास्केल के लिए लागू नहीं हो सकता है IO, क्योंकि उत्तरार्द्ध बातचीत, संगामिति और नॉनडेटर्मिनिज़्म का समर्थन करता है। इस सवाल का मेरा जवाब कुछ और संकेत के लिए देखें।
कोनल

2
@ जोनल जीएचसी वास्तव में IOइस तरह से लागू होता है , लेकिन RealWorldवास्तव में वास्तविक दुनिया का प्रतिनिधित्व नहीं करता है, यह सिर्फ संचालन को बनाए रखने के लिए एक टोकन है ("जादू" यह है कि RealWorldजीएचसी हास्केल का एकमात्र विशिष्ट प्रकार है)
जेरेमी सूची

2
@JeremyList जैसा कि मैं इसे समझता हूं, जीएचसी IOइस प्रतिनिधित्व और गैर-मानक संकलक जादू ( केन थॉम्पसन के प्रसिद्ध सी संकलक वायरस की याद ताजा) के संयोजन के माध्यम से लागू करता है । अन्य प्रकारों के लिए, सत्य स्रोत कोड में सामान्य हास्केल शब्दार्थों के साथ है।
कॉनल

1
@ क्लोनल मेरी टिप्पणी GHC स्रोत कोड के प्रासंगिक भागों को पढ़ने के कारण थी।
जेरेमी सूची

43

क्या कोई इस बात पर कुछ संकेत दे सकता है कि हास्केल में अप्रयुक्त संगणना को मोनाड के रूप में क्यों बनाया गया है?

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

अधिक स्पष्टीकरण के लिए, यह उत्तर देखें ।

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


1
@ केनीटीएम: लेकिन RealWorldजैसा कि डॉक्स कहते हैं, "गहरा जादुई"। यह एक टोकन है जो दर्शाता है कि रनटाइम सिस्टम क्या कर रहा है, यह वास्तव में वास्तविक दुनिया के बारे में कुछ भी मतलब नहीं है। आप अतिरिक्त चालबाजी किए बिना एक "धागा" बनाने के लिए एक नए को जोड़ नहीं सकते हैं; भोली दृष्टिकोण बस एक ही पैदा करेगा, जब यह चलेगा के बारे में बहुत अस्पष्टता के साथ कार्रवाई अवरुद्ध।
सीए मैककैन

4
इसके अलावा, मैं तर्क था कि monads हैं प्रकृति में अनिवार्य रूप से अनिवार्य। यदि फ़नकार इसमें अंतर्निहित मानों के साथ कुछ संरचना का प्रतिनिधित्व करता है, तो एक सनक उदाहरण का मतलब है कि आप उन मूल्यों के आधार पर नई परतों का निर्माण और सपाट कर सकते हैं। तो जो भी अर्थ आप फन्नेकार की एक परत पर असाइन करते हैं, एक भिक्षु का अर्थ है कि आप एक से दूसरे तक जाने वाले कार्य-कारण की एक सख्त धारणा के साथ एक निर्बाध संख्या बना सकते हैं। विशिष्ट उदाहरणों में आंतरिक रूप से अनिवार्य संरचना नहीं हो सकती है, लेकिन Monadसामान्य रूप से वास्तव में ऐसा होता है।
सीए मैककैन

3
" Monadसामान्य रूप से" मेरा मतलब है मोटे तौर पर forall m. Monad m => ..., यानी, एक मनमाना उदाहरण पर काम करना। मनमाने ढंग से मोनाड के साथ आप जो चीजें कर सकते हैं वे लगभग वही चीजें हैं जो आप के साथ कर सकते हैं IO: अपारदर्शी प्राइमेटिव प्राप्त करें (जैसा कि फ़ंक्शन तर्क, या पुस्तकालयों से, क्रमशः), के साथ नो-ऑप्स का निर्माण करें return, या एक अपरिवर्तनीय तरीके से एक मूल्य का उपयोग करें। (>>=)। एक मनमाने ढंग से मोनाड में प्रोग्रामिंग का सार अपरिवर्तनीय कार्यों की एक सूची उत्पन्न कर रहा है: "एक्स एक्स करें, फिर वाई करें, फिर ..."। मेरे लिए बहुत जरूरी लगता है!
सीए मैककैन

2
नहीं, तुम अब भी मेरी बात याद कर रहे हो। बेशक आप उन विशिष्ट प्रकारों में से किसी के लिए भी उस मानसिकता का उपयोग नहीं करेंगे, क्योंकि उनके पास स्पष्ट, सार्थक संरचना है। जब मैं कहता हूं कि "मनमाने सन्यासी" मेरा मतलब है कि "आपको लेने के लिए नहीं मिलता है"; यहाँ परिप्रेक्ष्य परिमाणक के अंदर से है, इसलिए mअस्तित्व के रूप में सोचना अधिक सहायक हो सकता है। इसके अलावा, मेरी "व्याख्या" एक है कानूनों की रीफ़्रेशिंग है; "डू एक्स" स्टेटमेंट की सूची अज्ञात संरचना के माध्यम से मुक्त मोनॉयड है (>>=); और मोनोएड कानून एंडोफूनर रचना पर सिर्फ मोनोइड कानून हैं।
सीए मैक्कैन

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

13

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


3
काफी नहीं। यह ज्ञात है कि एक मोनाड बहुत लंबे समय तक व्याख्या कर सकता है (कम से कम "टोपोई: ए श्रेणीवाचक तर्क का तर्क)। दूसरी ओर, यह स्पष्ट रूप से टाइप किए गए कार्यात्मक तक भिक्षुओं के प्रकारों को स्पष्ट रूप से व्यक्त करना संभव नहीं था। भाषाओं के आसपास आया था, और उसके बाद Moggi दो और दो को एक साथ रखा।
nomen

1
हो सकता है कि मानस को समझना आसान हो, अगर वे मानचित्र के आवरण के संदर्भ में परिभाषित किए गए थे और वापसी के साथ लिपटे नहीं थे।
aoeu256

9

क्या कोई इस बात पर कुछ संकेत दे सकता है कि हास्केल में अप्रयुक्त संगणना को मोनाड के रूप में क्यों बनाया गया है?

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

इसका मतलब है कि आपको कुछ प्रकार के साथ समाप्त करना होगा जो IO aएक अनपिट कम्प्यूटेशन मॉडल करते हैं। फिर आपको संयोजन के तरीकों को जानने की आवश्यकता है इन गणनाओं जो क्रम में लागू होते हैं ( >>=) और एक मान उठाते हैं (return हैं ) सबसे स्पष्ट और बुनियादी हैं।

इन दोनों के साथ, आप पहले से ही एक सन्यासी को परिभाषित कर चुके हैं (इसके बारे में भी सोचे बिना);)

इसके अलावा, मोनाड बहुत सामान्य और शक्तिशाली सार प्रदान करते हैं , इसलिए नियंत्रण के कई प्रकारों को आसानी से सामान्य कार्यों में सामान्यीकृत किया जा सकता है sequence, जैसे किliftM या विशेष वाक्यविन्यास, ऐसा कोई विशेष मामला नहीं है।

अधिक जानकारी के लिए कार्यात्मक प्रोग्रामिंग और विशिष्टता टाइपिंग में मोनड्स देखें (एकमात्र विकल्प जो मुझे पता है)।


6

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

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

ठीक है, तो हम इस ऑपरेशन के बारे में क्या कह सकते हैं? यह साहचर्य है; अगर हम तीन साइड इफेक्ट्स को मिलाते हैं, तो इससे कोई फर्क नहीं पड़ता कि हम किस ऑर्डर में संयोजन कर रहे हैं। यदि हम करते हैं (फाइल लिखते हैं तो सॉकेट पढ़ें), फिर कंप्यूटर को शटडाउन करें, यह लिखने की फाइल करने के समान ही है (तब सॉकेट पढ़ें) संगणक)। लेकिन यह सराहनीय नहीं है: ("फ़ाइल लिखें" तो "फ़ाइल हटाएं") "फ़ाइल हटाएं" (फिर "फ़ाइल लिखें") से एक अलग साइड इफेक्ट है। और हमारे पास एक पहचान है: विशेष साइड इफेक्ट "नो साइड इफेक्ट्स" काम करता है ("कोई साइड इफेक्ट नहीं" तो "डिलीट फाइल" उसी तरह का साइड इफेक्ट है जैसे "डिलीट फाइल") इस बिंदु पर कोई भी गणितज्ञ "ग्रुप" सोच रहा है! लेकिन समूहों में उलटा होता है, और सामान्य रूप से साइड इफेक्ट को पलटने का कोई तरीका नहीं है; "फ़ाइल को हटाएं" अपरिवर्तनीय है। इसलिए हमने जो संरचना छोड़ी है, वह एक भिक्षु की है, जिसका अर्थ है कि हमारे पक्ष प्रभाव वाले कार्य मठ होने चाहिए।

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


4

कार्यात्मक रूप से I / O के बारे में सोचना वास्तव में काफी साफ तरीका है।

अधिकांश प्रोग्रामिंग भाषाओं में, आप इनपुट / आउटपुट ऑपरेशन करते हैं। हास्केल में, लिखने का कोड संचालन न करने के लिए कल्पना करें , लेकिन उन कार्यों की एक सूची उत्पन्न करने के लिए जो आप करना चाहते हैं।

मोनाड ठीक उसी के लिए बहुत सुंदर वाक्यविन्यास हैं।

यदि आप यह जानना चाहते हैं कि भिक्षुओं ने किसी और चीज़ का विरोध क्यों किया, तो मुझे लगता है कि इसका उत्तर यह है कि वे I / O का प्रतिनिधित्व करने का सबसे अच्छा तरीका है कि लोग यह सोच सकें कि जब वे हास्केल बना रहे थे।


3

AFAIK, इसका कारण प्रकार प्रणाली में साइड इफेक्ट की जांच शामिल करने में सक्षम होना है। यदि आप अधिक जानना चाहते हैं, तो उन एसई-रेडियो एपिसोड्स को सुनें : एपिसोड 108: साइमन पेटन जोन्स ऑन फंक्शनल प्रोग्रामिंग और हास्केल एपिसोड 72: लिनिक पर एरिक मीजर


2

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

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

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

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

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

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

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

अंत में, मैं कहना चाहता हूं, कि सन्यासी अशुद्ध कार्यों को शुद्ध में नहीं बदलते हैं। यह केवल उन्हें प्रभावी ढंग से अलग करने की अनुमति देता है। (मैं दोहराता हूं, कि यह केवल मेरी समझ है)


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

Aoeu256 की यह टिप्पणी "क्यों" है जो अब तक दिए गए सभी स्पष्टीकरणों में गायब है। (अर्थात: सन्यासी मनुष्य के लिए नहीं, बल्कि संकलक के लिए हैं)
जोओ ओटेरो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.