简化Haskell代码

时间:2014-01-11 11:54:36

标签: haskell monads haskell-snap-framework

我正在使用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,所以这里应该有一些东西。另一件事是,do中也有register。任何指针都表示赞赏。

1 个答案:

答案 0 :(得分:6)

您的新代码没有任何问题。它比原始版本更长的部分原因是您正在处理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"

我使用maybe中的Data.Maybe函数来消除显式处理JustNothing值的需要。此功能仅定义为

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