我有以下代码,我觉得它很难看:
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")]
这段代码似乎非常迫切。我能以某种方式简化它吗?
答案 0 :(得分: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检查,那就有点危险了。
这可以通过
来改进答案 1 :(得分: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")] )
......实际上上面的内容现在让我看起来很好看
答案 2 :(得分: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")]
多么烦人。
答案 3 :(得分: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
答案 4 :(得分: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")]
答案 5 :(得分: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