【问题标题】:Simplify Haskell Code简化 Haskell 代码
【发布时间】:2014-01-11 11:54:35
【问题描述】:

我正在处理 Snap 框架中的 Haskell 代码。一切正常,但现在我需要清理一些代码。然而,经过几次尝试,我似乎只有更多的代码。也许有人可以给我一些指点?

这是我的初始代码。问题是,我对 Maybe 值进行模式匹配,这在我看来是非常错误的。所以我想把它排除在外。但是下一行会得到一个Maybe 值,所以我不得不改变它..

handleNewUserPost :: Handler App (AuthManager App) ()
handleNewUserPost = do
    Just username <- getPostParam "login"
    exists <- usernameExists $ T.decodeUtf8 username
    case exists of
        True    -> handleNewUserGet $ Just "Sorry, this username already exist."
        False   -> do
            registerUser "login" "password"
            redirect "/new_user"

最终我想到了这个:

handleNewUserPost :: Handler App (AuthManager App) ()
handleNewUserPost = do
    username <- getPostParam "login" -- :t username = Maybe ByteString
    validate username
    where 
      validate Nothing = redirect "/new_user"
      validate (Just username) = do exists <- existcheck username
                                    if exists
                                      then userexists
                                      else register
      existcheck :: C.ByteString -> Handler b (AuthManager b) Bool
      existcheck username = (usernameExists . T.decodeUtf8) $ username
      userexists          =  handleNewUserGet $ Just "Sorry, this username already exist."
      register            = do registerUser "login" "password"
                               redirect "/new_user"

问题在于我觉得我也不应该对Nothing 进行模式匹配。我在do,所以这里应该有一些东西。另一件事是,我在register 中也有一个do。任何指针表示赞赏。

【问题讨论】:

  • 这可能更适合 codereview.stackexchange.com。但基本上我认为你的新代码很好。请记住,您确实通过添加 validate Nothing 案例使其更加健壮。

标签: haskell monads haskell-snap-framework


【解决方案1】:

您的新代码没有任何问题。它比原始代码更长的部分原因是您正在处理 Nothing 案例,而您最初并没有这样做(因此您的新代码更安全)。如果你想把它整理一下,你可以写成

handleNewUserPost :: Handler App (AuthManager App) ()
handleNewUserPost =
  getPostParam "login" >>= maybe (redirect "/new_user") validateUser
 where
  validateUser username = do
    exists <- usernameExists $ T.decodeUtf8 username
    if exists
      then handerNewUserGet $ Just "Sorry, this username already exists."
      else do
        registerUser "login" "password"
        redirect "/new_user"

我使用了来自Data.Maybe 的函数maybe 来消除显式处理JustNothing 值的需要。这个函数只是定义为

maybe :: b -> (a -> b) -> Maybe a -> b
maybe b _ Nothing  = b
maybe _ f (Just a) = f a

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-16
    • 2011-02-24
    • 2011-08-09
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多