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")]

このコードは非常に必須のようです。何とか簡略化できますか?

4

6 に答える 6

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 チェックが間違っていると少し危険です。

これは次の方法で改善できます。

  • 上記のようなパターンマッチング。しかし、これがネストされていると、見苦しくなります。
  • fromMaybe のようなコンビネータは、より簡潔にすることができます。
  • Maybe (および MaybeT) を Applicative または Monad として使用すると、見苦しいネストを回避できます。
于 2012-06-19T20:53:38.340 に答える
9

他の人が示唆しているように、ここでも、文脈によってはApplicativeいいかもしれません。MaybeT覚えておくべき 3 番目のことは、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")] )

...実際、上記は私がそれを見るとかなりばかげています

于 2012-06-20T00:15:38.593 に答える
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")]

面倒くさい。

于 2012-06-19T20:54:12.510 に答える
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
于 2012-06-19T22:54:23.277 に答える
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")]
于 2012-06-19T22:55:58.957 に答える
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       
于 2012-06-21T00:31:37.490 に答える