简化Haskell代码

Chr*_*yer 2 monads haskell 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"
Run Code Online (Sandbox Code Playgroud)

最终我来到这里:

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"
Run Code Online (Sandbox Code Playgroud)

这个问题是我有一种感觉,我不应该对这Nothing两种方式进行模式匹配.我在do,所以这里应该有一些东西.另一件事是,我有一个doregister为好.任何指针都表示赞赏.

Chr*_*lor 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"
Run Code Online (Sandbox Code Playgroud)

这里我用的函数maybeData.Maybe删除需要明确地处理JustNothing值.此功能仅定义为

maybe :: b -> (a -> b) -> Maybe a -> b
maybe b _ Nothing  = b
maybe _ f (Just a) = f a
Run Code Online (Sandbox Code Playgroud)