मैं किस फ़ंक्शन का उपयोग करता हूं?
यहाँ Control.Exception प्रलेखन से सिफारिश की गई है:
- यदि आप इस घटना में कुछ सफाई करना चाहते हैं कि एक अपवाद उठाया, उपयोग
finally, bracketया है onException।
- एक अपवाद के बाद ठीक होने और कुछ और करने के लिए,
tryपरिवार में से किसी एक का उपयोग करने के लिए सबसे अच्छा विकल्प है ।
- ... जब तक आप एक अतुल्यकालिक अपवाद से पुनर्प्राप्त नहीं कर रहे हैं, जिस स्थिति में उपयोग करें
catchया catchJust।
प्रयास करें :: अपवाद e => IO a -> IO (Either ea)
tryIOचलाने के लिए एक कार्रवाई करता है, और एक रिटर्न देता है Either। यदि गणना सफल हुई, तो परिणाम एक Rightकंस्ट्रक्टर में लिपटे हुए है । (गलत के विपरीत सही समझें)। यदि क्रिया निर्दिष्ट प्रकार के अपवाद को फेंक देती है , तो उसे एक Leftनिर्माता में वापस कर दिया जाता है । यदि अपवाद उपयुक्त प्रकार का नहीं था , तो यह स्टैक का प्रचार करना जारी रखता है। SomeExceptionप्रकार के रूप में निर्दिष्ट करना सभी अपवादों को पकड़ लेगा, जो एक अच्छा विचार हो सकता है या नहीं भी हो सकता है।
ध्यान दें कि यदि आप एक शुद्ध संगणना से एक अपवाद को पकड़ना चाहते हैं, तो आपको evaluateमूल्यांकन को बल देने के लिए उपयोग करना होगा try।
main = do
result <- try (evaluate (5 `div` 0)) :: IO (Either SomeException Int)
case result of
Left ex -> putStrLn $ "Caught exception: " ++ show ex
Right val -> putStrLn $ "The answer was: " ++ show val
पकड़ :: अपवाद e => IO a -> (e -> IO a) -> IO a
catchके समान है try। यह पहले निर्दिष्ट IOकार्रवाई को चलाने की कोशिश करता है , लेकिन अगर एक अपवाद को फेंक दिया जाता है तो हैंडलर को एक वैकल्पिक उत्तर प्राप्त करने के लिए अपवाद दिया जाता है।
main = catch (print $ 5 `div` 0) handler
where
handler :: SomeException -> IO ()
handler ex = putStrLn $ "Caught exception: " ++ show ex
हालांकि, एक महत्वपूर्ण अंतर है। catchअपने हैंडलर का उपयोग करते समय एक एसिंक्रोनस अपवाद द्वारा बाधित नहीं किया जा सकता है (यानी किसी अन्य थ्रेड के माध्यम से फेंक दिया जाता है throwTo)। जब तक आपके हैंडलर ने दौड़ना समाप्त नहीं किया है, तब तक एक विषम अपवाद को उठाने का प्रयास अवरुद्ध होगा।
ध्यान दें कि catchप्रस्तावना में एक अलग है, इसलिए आप करना चाह सकते हैं import Prelude hiding (catch)।
संभाल :: अपवाद e => (e -> IO a) -> IO a -> IO a
handleबस catchउलटे क्रम में तर्कों के साथ है। कौन सा उपयोग करना है यह इस बात पर निर्भर करता है कि आपके कोड को अधिक पठनीय बनाता है, या यदि आप आंशिक अनुप्रयोग का उपयोग करना चाहते हैं तो कौन बेहतर है। वे अन्यथा समान हैं।
tryJust, catchJust और handleJust
ध्यान दें कि try, catchऔर निर्दिष्ट / अनुमानित प्रकार के सभी अपवादों handleको पकड़ लेगा । और मित्र आपको एक चयनकर्ता फ़ंक्शन निर्दिष्ट करने की अनुमति देते हैं जो फ़िल्टर करता है जो विशेष रूप से आप संभालना चाहते हैं। उदाहरण के लिए, सभी अंकगणितीय त्रुटियाँ प्रकार की हैं । यदि आप केवल पकड़ना चाहते हैं , तो आप कर सकते हैं:tryJustArithExceptionDivideByZero
main = do
result <- tryJust selectDivByZero (evaluate $ 5 `div` 0)
case result of
Left what -> putStrLn $ "Division by " ++ what
Right val -> putStrLn $ "The answer was: " ++ show val
where
selectDivByZero :: ArithException -> Maybe String
selectDivByZero DivideByZero = Just "zero"
selectDivByZero _ = Nothing
शुद्धता पर ध्यान दें
ध्यान दें कि इस प्रकार का अपवाद हैंडलिंग केवल अशुद्ध कोड (यानी IOमोनाड) में हो सकता है। यदि आपको शुद्ध कोड में त्रुटियों को संभालने की आवश्यकता है, तो आपको Maybeया Either(या कुछ अन्य बीजीय डेटाटाइप) का उपयोग करके लौटने वाले मूल्यों पर ध्यान देना चाहिए । यह अक्सर बेहतर होता है क्योंकि यह अधिक स्पष्ट होता है इसलिए आप हमेशा जानते हैं कि क्या हो सकता है। Control.Monad.Errorइस तरह के त्रुटि के साथ काम करने के लिए मोनाड इस तरह की त्रुटि को आसान बनाते हैं।
यह सभी देखें: