2012-08-26 11 views
5

के साथ ढेर हो सकता है मैं एक प्राधिकरण योजना सेट करने की कोशिश कर रहा हूं जहां मैं इसे जांचता हूं 1. उपयोगकर्ता लॉग इन है 2. उपयोगकर्ता के पास एक निश्चित वस्तु तक पहुंच है। इसके लिए मैं पहले maybeAuthId पर कॉल करता हूं, फिर वर्तमान ऑब्जेक्ट प्राप्त करने का प्रयास करें, और अनुमतियों को सूचीबद्ध करने वाली किसी अन्य तालिका में 'शामिल हों'। हो सकता है कि मामले के दो स्तर और रिक्त-सूची मामले का एक स्तर हो। मैंने शायद होट का उपयोग करने के बारे में सोचा, लेकिन या तो मैं इसे काम करने के लिए बहुत थक गया हूं या "वास्तव में मोनैड ट्रांसफार्मर नहीं" -हैंडर-ट्रांसफार्मर का उपयोग शायद टी के साथ नहीं किया जा सकता है। गहरी मेबों को संभालने का कोई अच्छा तरीका है?दीप शायद हांद

संपादित करें:

मैं ऐसा कुछ अस्पष्ट था। मैं का मतलब है कि मैं कुछ इस तरह है:

case foo of 
    Nothing -> something 
    Just foo' -> do 
     bar <- somethingelse 
     case bar of 
     Nothing -> ... 
     Just bar' -> ... 

उत्तर

6

आप यसोड के लिए MaybeT का पूरी तरह से उपयोग कर सकते हैं। बस इसे इस तरह है:

runMaybeT $ do 
    uid <- MaybeT maybeAuthID 
    car <- MaybeT . runDB . getBy $ UniqueCarOwner uid 
    location <- MaybeT . liftIO . ciaLocateLicensePlate . licensePlate $ car 
    country <- MaybeT . findCountry $ location 
    return (car, country) 

जैसा कि आपने कहा, अधिकांश कार्यों को Yesod में से निपटने के सामान्य त्रुटि के लिए अनुकूलित नहीं कर रहे हैं। हालांकि, अगर आपके पास Monad m => m (Maybe a) फॉर्म का कुछ है, तो आप इसे का उपयोग Monad m => Maybe (m a) में बदलने के लिए कर सकते हैं।

+0

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

1

यह बिल्कुल स्पष्ट है कि तुम क्या इसका मतलब यह नहीं है "संभाल गहरी Maybes" द्वारा, लेकिन आप उपयोग कर सकते हैं monadic join (Control.Monad से) एक समय में घोंसले में से एक स्तर को दूर करने के।

ghci> :m +Control.Monad 
ghci> join (Just (Just 3)) 
Just 3 
ghci> join (Just Nothing) 
Nothing 
ghci> join Nothing 
Nothing 

MaybeT का प्रयोग शायद आपकी समस्या के लिए एक बेहतर फिट है, हालांकि है। यदि आप यह स्पष्ट करते हैं कि आप क्या करने का प्रयास कर रहे हैं, तो हम इसे होट के साथ फ़ॉर्मूलेट करने में आपकी सहायता कर सकते हैं।

2

मैं क्या समझ से, अपने परतों की तरह लग रहे:

Maybe [Maybe r] 

... और आप join करने के लिए दो Maybe एक साथ एस चाहते हैं, लेकिन सूची रास्ते में है। यह ठीक समस्या sequence को हल करती है:

sequence :: (Monad m) => [m r] -> m [r] 

ध्यान दें कि अगर हम Maybe इकाई को sequence विशेषज्ञ हम पाते हैं:

sequence :: [Maybe r] -> Maybe [r] 

इस विशेष मामले में, sequence एक Nothing वापस आ जाएगी अगर वहाँ कम से कम है सूची में एक Nothing, लेकिन यदि वे सभी Just एस हैं, तो यह उन सभी को एक Just में शामिल करेगा।

join . fmap sequence :: Maybe [Maybe r] -> Maybe [r] 

तो, सहज, क्या इसके बाद के संस्करण समारोह:

fmap sequence :: Maybe [Maybe r] -> Maybe (Maybe [r]) 

अब इस फार्म हम में शामिल होने के लिए की जरूरत है ठीक है:

सभी कि रहता बाहरी Maybe से अधिक sequence मैप करने के लिए है ऐसा है कि यदि सभी आंतरिक Maybe एस Just एस हैं और बाहरी MaybeJust है, तो यह पूरे परिणाम को एक Just में फ़्यूज़ करता है जिसमें युक्त सूची। हालांकि, अगर Maybe (या तो आंतरिक वाले या बाहरी एक) Nothing है, तो अंतिम परिणाम Nothing है।

ध्यान दें कि अंधेरे प्रकार के पीछा का एक गुच्छा करने के बावजूद, हम एक ऐसे कार्य के साथ समाप्त हुए जो सहजता से सही काम करता है। यह श्रेणी सिद्धांत में आधारित abstractions की शक्ति है।

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