क्या कोई बता सकता है कि आईओ मोनैड के बाहर अपवाद क्यों फेंक दिए जा सकते हैं, लेकिन केवल इसके अंदर पकड़ा जा सकता है?हास्केल अपवाद केवल आईओ मोनैड के अंदर क्यों पकड़े जा सकते हैं?
उत्तर
कारणों में से एक denotational semantics of Haskell है। अधिक परिभाषित तर्क पैदावार अधिक परिभाषित मूल्य -
(शुद्ध) हास्केल कार्यों का साफ प्रॉपर्टीज़ में से एक उनके दिष्टता है। यह संपत्ति बहुत महत्वपूर्ण है उदा। पुनरावर्ती कार्यों के बारे में कारण (समझने के लिए लेख पढ़ें) क्यों।
परिभाषा द्वारा अपवाद का नोटेशन नीचे दिया गया है, _|_
, दिए गए प्रकार से संबंधित पॉकेट में कम से कम तत्व। इस प्रकार, दिष्टता आवश्यकता को पूरा करने के लिए, निम्न असमानता हास्केल समारोह के किसी भी वाच्यार्थ f
के लिए पकड़ करने के लिए की जरूरत है:
f(_|_) <= f(X)
अब, अगर हम अपवाद पकड़ सकते थे, हम (द्वारा "पहचानने" नीचे इस असमानता को तोड़ सकते थे पकड़ने अपवाद) तथा लौटने अधिक परिभाषित मूल्य:
f x = case catch (seq x True) (\exception -> False) of
True -> -- there was no exception
undefined
False -> -- there was an exception, return defined value
42
यहाँ पूरा काम कर प्रदर्शन है (की आवश्यकता आधार -4 Control.Exception):
import Prelude hiding (catch)
import System.IO.Unsafe (unsafePerformIO)
import qualified Control.Exception as E
catch :: a -> (E.SomeException -> a) -> a
catch x h = unsafePerformIO $ E.catch (return $! x) (return . h)
f x = case catch (seq x True) (\exception -> False) of
True -> -- there was no exception
undefined
False -> -- there was an exception, return defined value
42
एक अन्य कारण, जैसा कि टॉमएमडी ने नोट किया, संदर्भित पारदर्शिता तोड़ रहा है। आप बराबर चीजों को बराबर के साथ प्रतिस्थापित कर सकते हैं और एक और जवाब प्राप्त कर सकते हैं। (Denotational भावना में बराबर, यानी वे ==
भावना में नहीं, एक ही मूल्य को दर्शाते हैं।)
हम यह कैसे करेंगे? निम्नलिखित अभिव्यक्ति पर विचार करें:
let x = x in x
यह एक गैर-सांत प्रत्यावर्तन है, इसलिए यह कभी नहीं हमें किसी भी जानकारी देता है और इस तरह _|_
द्वारा भी दिखाया जाता है। अगर हम अपवादों को पकड़ने के लिए सक्षम थे, हम समारोह लिख सकता है च जैसे
f undefined = 0
f (let x = x in x) = _|_
(उत्तरार्द्ध हमेशा सख्ती से पालन कार्यों के लिए सच है, क्योंकि हास्केल गैर समाप्त गणना पता लगाने के लिए कोई साधन प्रदान करता है - और सिद्धांत रूप में नहीं कर सकते हैं, Halting problem की वजह से।)
क्योंकि अपवाद referential transparency तोड़ सकता है।
आप शायद अपवाद है कि वास्तव में इनपुट के प्रत्यक्ष परिणाम हैं के बारे में बात कर रहे हैं। उदाहरण के लिए:
head [] = error "oh no!" -- this type of exception
head (x:xs) = x
आप इस तरह त्रुटियों को पकड़ने के लिए सक्षम नहीं होने का रोना रोते रहे हैं तो मैं तुम्हें करने के लिए दावा है कि कार्यों error
या किसी अन्य अपवादों के नहीं भरोसा किया जाना चाहिए, लेकिन इसके बजाय (एक उचित वापसी प्रकार का उपयोग करना चाहिए Maybe
, Either
, या शायद MonadError)। यह आपको असाधारण स्थिति से अधिक स्पष्ट तरीके से निपटने के लिए मजबूर करता है।
ऊपर (और क्या अपने प्रश्न के पीछे समस्या होती है) के विपरीत, अपवाद जैसे स्मृति की स्थिति है कि मूल्य का अभिकलन किया जा रहा है पूरी तरह से स्वतंत्र हैं से बाहर के रूप में संकेतों से हो सकता है। यह स्पष्ट रूप से एक शुद्ध अवधारणा नहीं है और आईओ में रहना चाहिए।
क्या आप इस तरह से रेफरेंसियल पारदर्शिता तोड़ने का एक उदाहरण दे सकते हैं? –
तो आप मुझे बताना चाहते हैं कि उत्साह कार्यशील रूप से सोचने का तरीका नहीं है, इसलिए मुझे आम तौर पर उनसे बचने की कोशिश करनी चाहिए? महान! – fuz
रोमन: मेरा क्या मतलब था कि यदि आप शुद्ध कोड में अपवाद प्राप्त कर सकते हैं और उन अपवादों पर अपना परिणाम आधार दे सकते हैं, तो ऐसी कार्रवाई रेफरेंसियल पारदर्शिता को तोड़ देगी। –
मैं अपने विवरण में गलत हो सकता है, लेकिन इस तरह मैं यह समझ है।
चूंकि कार्य हास्केल में शुद्ध हैं, इसलिए संकलक को उनके इच्छित किसी भी क्रम में उनका मूल्यांकन करने का अधिकार है और यह अभी भी एक ही परिणाम उत्पन्न करता है। उदाहरण के लिए, दिए गए कार्य:
square :: Int -> Int
square x = x * x
अभिव्यक्ति square (square 2)
अलग अलग तरीकों से मूल्यांकन किया जा सकता, लेकिन यह हमेशा एक ही परिणाम है जो 16
है अगर हम कहीं और से square
कॉल करने के लिए कम कर देता है:
test x = if x == 2
then square x
else 0
square x
का मूल्यांकन बाद में मूल्यांकन किया जा सकता है, जब test
फ़ंक्शन को वास्तव में आवश्यक होने पर "बाहर" किया जा सकता है। उस पल में कॉल स्टैक जावा से कहने की अपेक्षा से बिल्कुल अलग हो सकता है।
तो अगर हम square
द्वारा फेंकने वाले संभावित अपवाद को पकड़ना चाहते हैं, तो आपको catch
भाग कहां रखना चाहिए?
- 1. हास्केल एक्सटेंसिबल आईओ अपवाद?
- 2. मेरे सी ++ अपवाद क्यों नहीं पकड़े जा रहे हैं?
- 3. हास्केल। गैर आईओ अपवाद हैंडलिंग
- 4. हास्केल आईओ
- 5. आईओ के बाहर हास्केल एचएफटी चल रहा है?
- 6. मोनैड
- 7. टेम्पलेट हास्केल और आईओ
- 8. हास्केल आईओ: वास्तविक प्रकार
- 9. हास्केल आईओ परीक्षण
- 10. हास्केल
- 11. रनटाइम अपवाद एसीआरए के साथ पकड़े जाते हैं और लॉगकैट
- 12. हास्केल में अपने स्वयं के मोनड में आईओ कैसे जोड़ें?
- 13. पहले से पकड़े जाने के बाद अपवाद प्रचार
- 14. हास्केल "अपवाद"
- 15. प्रतिबिंब अपवाद पकड़े जाने में असमर्थ?
- 16. स्ट्रक्चर के अंदर गैर स्थैतिक फ़ील्ड क्यों शुरू नहीं किए जा सकते हैं?
- 17. अपवाद पकड़े जाने पर gdb का उपयोग वापस करने के लिए किया जा सकता है?
- 18. टस्कल्स के अंदर हास्केल तीर
- 19. हास्केल रीडरटी एनवी आईओ बॉयलरप्लेट
- 20. हास्केल आईओ (स्ट्रिंग) और स्ट्रिंग
- 21. स्पिनलॉक पकड़े हुए आप सो क्यों नहीं सकते?
- 22. लॉगिंग पकड़े गए और अनचाहे अपवाद?
- 23. हास्केल में आईओ पर मैपिंग
- 24. हास्केल आईओ सहभागिता और नक्शा
- 25. जावास्क्रिप्ट/node.js में lambdas में अपवाद पकड़े गए हैं?
- 26. हास्केल में अपवाद कैसे काम करते हैं?
- 27. हास्केल: मैंने अभी क्या मोनैड किया था?
- 28. मोनैड
- 29. क्यों पाइथन सजावट परिभाषाओं में बंधे नहीं जा सकते हैं?
- 30. क्या sys.exit() से पकड़े गए SystemExit अपवाद को पकड़े जाने से रोकने का कोई तरीका है?
ठीक है। यह हैकेल के पीछे कठिन गणितीय बैकग्राउंड में से एक प्रतीत होता है। आपके संक्षिप्त विवरण के लिए धन्यवाद। – fuz
क्षमा करें, लेकिन यह जवाब पूरी तरह से परेशान है जो मुझे लगता है कि यह एक बहुत ही सरल सवाल है ... लेकिन यह शायद आपके उत्तर के बजाय हास्केल की समझ की कमी पर अधिक दर्शाता है। –
dodgy_coder: मुझे खेद है कि यह आपके लिए उपयोगी नहीं था। ऐसे कई दृष्टिकोण हो सकते हैं जिनसे कोई इस प्रश्न का उत्तर दे सकता है। आप कह सकते हैं कि आप इसे (नहीं) कर सकते हैं क्योंकि संबंधित कार्यों के प्रकार इसे नहीं करते हैं (नहीं)। तो निश्चित रूप से आप पूछ सकते हैं कि वे प्रकार क्यों हैं। जवाब यह है कि "ऐसी चीजों को अनुमति देने के लिए अच्छे कारण नहीं हैं", और मैंने ऊपर दिए गए कारणों की रूपरेखा तैयार करने की कोशिश की। –