2011-12-22 7 views
5

मेरे पास हैस्केल में त्रुटियों से निपटने के लिए निम्नलिखित मोनैड ट्रांसफॉर्मर है।हास्केल monads और एक विफल है कि एक स्ट्रिंग की आवश्यकता नहीं है

instance (Monad m, Error e) => Monad (EitherT e m) where 
    return = EitherT . return . return 
    m >>= k = EitherT $ do 
      a <- runEitherT m 
      case a of 
       Left l -> return (Left l) 
       Right r -> runEitherT (k r) 
    fail = EitherT . return . Left . strMsg 

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

fail क्योंकि यह String -> EitherT e m टाइप है, और String प्रतिबंध एक कष्टप्रद तरह से त्रुटियों को बनाने के लिए किया जा सकता है, थोड़ा पागल है, हालांकि। मैं की एक पूरी बहुत कुछ के साथ अंत:

instance Error BazError where 
    strMsg "foo" = FooError -- oh look we have no error context 
    strMsg "bar" = BarError -- isn't that nice 

मैं क्या करना चाहते हैं क्या, fail की तरह एक नया कार्य बनाने के लिए, यह है कि प्रकार a -> e की है, ताकि मैं (Error e) प्रतिबंध हटा सकते हैं। fail जब इकाई ढेर बड़े हो जाता है, जब मैं

EitherT BazError (StateT [BazWarning] IO) Foo 

अंत की तरह वहाँ एक समारोह एक कम प्रतिबंधक प्रकार के साथ fail रूप में एक ही व्यवहार किया है कि बनाने के लिए एक रास्ता है विशेष रूप से सुविधाजनक है? या fail गहरे हैकेल अंधेरे जादू का उपयोग करके लागू किया गया है? यदि आप एक करते ब्लॉक में एक पैटर्न मैचों की विफलता है

+3

आपको शायद 'असफल' पूरी तरह से टालना चाहिए, जब तक आप असफल 'डू'-ब्लॉक पैटर्न मैचों पर व्यवहार को कस्टमाइज़ नहीं करना चाहते। – ehird

उत्तर

7

खैर, fail, कहा जाता है, जैसा कि आप Just x <- something है और something के परिणाम Nothing है। इसके अलावा, fail एक सामान्य कार्य है।

strMsg "foo" = FooError आदि के साथ समस्या के लिए, throwError आपके उपयोग के मामले के लिए एक अच्छा इंटरफेस प्रदान करता है?

4

इस लेख उपयोगी हो सकता है: http://blog.ezyang.com/2011/08/8-ways-to-report-errors-in-haskell-revisited/

आपका EitherT मानक पुस्तकालय में पहले से ही है और ErrorT कहा जाता है। प्रलेखन देखें: http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-Error.html#t:ErrorT

fail अब ऐतिहासिक जिज्ञासा है, और Functor a => Monad a बाधा की कमी के साथ डिज़ाइन दोष माना जा सकता है। do नोटेशन में असफल पैटर्न मैचों को संभालने के लिए यह केवल एक विवादास्पद विशेषता है।

throwError :: MonadError e m => e -> m a 

fail के लिए सबसे आम प्रतिस्थापन है, लेकिन अधिक उपलब्ध हैं (लेख देखें)।

संबंधित मुद्दे

 संबंधित मुद्दे