मैं किस फ़ंक्शन का उपयोग करता हूं?
यहाँ Control.Exception प्रलेखन से सिफारिश की गई है:
- यदि आप इस घटना में कुछ सफाई करना चाहते हैं कि एक अपवाद उठाया, उपयोग
finally
, bracket
या है onException
।
- एक अपवाद के बाद ठीक होने और कुछ और करने के लिए,
try
परिवार में से किसी एक का उपयोग करने के लिए सबसे अच्छा विकल्प है ।
- ... जब तक आप एक अतुल्यकालिक अपवाद से पुनर्प्राप्त नहीं कर रहे हैं, जिस स्थिति में उपयोग करें
catch
या catchJust
।
प्रयास करें :: अपवाद e => IO a -> IO (Either ea)
try
IO
चलाने के लिए एक कार्रवाई करता है, और एक रिटर्न देता है 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
को पकड़ लेगा । और मित्र आपको एक चयनकर्ता फ़ंक्शन निर्दिष्ट करने की अनुमति देते हैं जो फ़िल्टर करता है जो विशेष रूप से आप संभालना चाहते हैं। उदाहरण के लिए, सभी अंकगणितीय त्रुटियाँ प्रकार की हैं । यदि आप केवल पकड़ना चाहते हैं , तो आप कर सकते हैं:tryJust
ArithException
DivideByZero
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
इस तरह के त्रुटि के साथ काम करने के लिए मोनाड इस तरह की त्रुटि को आसान बनाते हैं।
यह सभी देखें: