2012-06-19 20 views
9

मैं निम्नलिखित कोड है भाव, और मुझे लगता है कि यह बदसूरत है:सरल हो सकता है कि

loginCheck = do 
    ml <- getPostParam "login" -- ml and mp :: Maybe ByteString 
    mp <- getPostParam "password" 
    if isJust ml && isJust mp 
    then authAs (fromJust ml) (fromJust mp) 
    else render "Msg" [("text", "Form incomplete")] 

इस कोड को बहुत जरूरी हो रहा है। क्या मैं इसे किसी भी तरह से सरल बना सकता हूं?

उत्तर

9

के रूप में सुझाव दिया है, Applicative यहाँ अच्छा हो सकता है, साथ ही MaybeT के रूप में संदर्भ के आधार पर। एक तीसरी चीज जो आप ध्यान में रख सकते हैं वह है कि do ब्लॉक बाध्यकारी कॉल fail में पैटर्न मिलान विफलता।

यह मैं क्या कर सकता है:

loginCheck = do 
    ml <- getPostParam "login" 
    mp <- getPostParam "password" 
    fromMaybe (render "Msg" [("text", "Form incomplete")]) $ 
      authAs <$> ml <*> mp 

या कोई भिन्न वापसी मान के साथ MaybeT के साथ एक समाधान, यद्यपि (फिर से अधिक संदर्भ यह दिखा सकता है एक अच्छा दृष्टिकोण है या नहीं होने के लिए):

getPostParamT = MaybeT . getPostParam 
loginCheckT = do 
    ml <- getPostParamT "login" -- ml and mp :: Maybe ByteString 
    mp <- getPostParamT "password" 
    liftIO $ authAs ml mp 
    <|> (liftIO $ render "Msg" [("text", "Form incomplete")]) 

... वास्तव में ऊपर अब बल्कि सस्ती है कि मैं इस पर पुन अपने दूसरे atte

+1

मुझे लगता है कि आपका पहला दृष्टिकोण बहुत से साफ है। मैं वही करता हूं, किसी भी तरह :)। –

+2

+1 जब मैंने तर्क के प्रकार की आवश्यकता देखी, तो मैंने तुरंत 'माईबे' + आवेदकों से सोचा। आपका 'सेबेबे' समाधान बहुत साफ है। हो सकता है कि समाधान खराब न हो; होप का उपयोग करने के लिए कोड के बड़े swaths refactoring ओपी के मामले में एक अच्छा विकल्प हो सकता है। –

12

कैसे के बारे में:

loginCheck = do 
    ml <- getPostParam "login" -- ml and mp :: Maybe ByteString 
    mp <- getPostParam "password" 
    case (ml,mp) of 
    (Just l, Just p) -> authAs l p 
    _ -> render "Msg" [("text", "Form incomplete")] 

कोड isJust का उपयोग करता है और/या fromJust लगभग हमेशा बुरा शैली और थोड़ा खतरनाक अगर आप fromJust गलत से पहले isJust जांच हो रही है।

यह ऊपर की तरह,

  • पैटर्न मिलान द्वारा सुधार किया जा जा सकता है। लेकिन अगर यह घोंसला है तो यह बदसूरत हो जाता है।
  • कॉम्बिनेटर्स, जैसे मेबे से अधिक संक्षिप्त हो सकते हैं।
  • आवेदक या मोनाड के रूप में शायद (और हो सकता है) का उपयोग कर बदसूरत घोंसले से बच सकते हैं।
4
loginCheck = case (,) <$> getPostParam "login" <*> getPostParam "password" of 
    Just (l, p) -> authAs l p 
    Nothing  -> render "Msg" [("text", "Form incomplete")] 

शायद? नहीं, ओह।

loginCheck = do 
    x <- (,) <$> getPostParam "login" <*> getPostParam "password" of 
    case x of 
    Just (l, p) -> authAs l p 
    Nothing  -> render "Msg" [("text", "Form incomplete")] 

कितना कष्टप्रद।

+0

देखो mpt: मुझे लगता है कि 'x :: (शायद बाइटस्ट्रिंग, शायद बाइटस्ट्रिंग)', नहीं 'x :: शायद (बाइटस्ट्रिंग, बाइटस्ट्रिंग) '। मज़ेदार '<$>' और '<*> 'चालू हैं' आईओ ',' शायद 'नहीं। – dave4420

+0

उसे पहले लिफ्टएम 2 जोड़ने की जरूरत है: 'liftM2 (,) <$> getPostParam" लॉगिन "<*> getPostParam" पासवर्ड ">> = \ res -> केस रेज ...' – applicative

2

अगर यह एक सुधार यहाँ है सुनिश्चित नहीं हैं, लेकिन शायद कुछ मामलों में ...

import Control.Monad 
import Control.Monad.Trans.Class 
import Control.Monad.Trans.Maybe 

getPostParam' = MaybeT . getPostParam 
render' x y = lift (render x y) 
authAs' x y = lift (authAs x y) 

loginCheck = runMaybeT $ 
     go `mplus` render' "Msg" [("text", "Form incomplete")] 
    where 
     go = do 
      ml <- getPostParam' "login" 
      mp <- getPostParam' "password" 
      authAs' ml mp 
+1

मुझे लगता है कि 'रेंडर' को परिभाषित नहीं करना क्लीनर है 'और' authAs ', और बस' लिफ्ट की इनलाइन लिखें, क्योंकि इस तरह के फ़ंक्शन को आमतौर पर एक से अधिक बार उपयोग नहीं किया जाएगा। –

2
loginCheck = do 
    [ml,mp] <- mapM getPostParam ["login","password"] 
    case liftM2 authAs ml mp of 
    Nothing   -> render "Msg" [("text", "Form incomplete")] 
    Just authorize -> authorize 

इसका कारण यह है कि यह पैटर्न एक Maybe (IO()) पर से मेल खाता है, लेकिन यह पूरी तरह से ध्वनि है अजीब लग सकता है। या, maybe का उपयोग कर: दूसरों

loginCheque = mapM getPostParam ["login","password"] >>= \[ml,mp] -> 
       maybe message id (liftM2 authAs ml mp) 
    where message = render "Msg" [("text", "Form incomplete")] 
+0

ओह, 'जेबेरमैन' द्वारा उल्लिखित 'सेबेबे' के बारे में भूल गया; जहां मैं 'शायद' का उपयोग करता हूं, यह सिर्फ 'मेबे संदेश से होना चाहिए (liftM2 authAs ...) ' – applicative

1
loginCheck = do 
    res <- return$ getPostParam "login" >>= \l -> -- ml and mp :: Maybe ByteString 
        getPostParam "password" >>= \p-> 
        Just (l,p) 
    case res of Nothing -> render "Msg" [("text", "Form incomplete")] 
       (Just (l,p)) -> authAs l p  
संबंधित मुद्दे