Упростить код на Haskell

Я работаю над кодом на Haskell в фреймворке Snap. Все работает, но теперь мне нужно очистить некоторый код. Однако после нескольких попыток кажется, что у меня просто больше кода. Может быть, кто-нибудь может дать мне несколько советов?

Это был мой начальный код. Дело в том, что я сопоставляю 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 ответ

Решение

Нет ничего плохого в вашем новом коде. Одна из причин того, что он длиннее оригинала, заключается в том, что вы обрабатываете 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 чтобы устранить необходимость явно обрабатывать Just или же Nothing ценности. Эта функция просто определяется как

maybe :: b -> (a -> b) -> Maybe a -> b
maybe b _ Nothing  = b
maybe _ f (Just a) = f a
Другие вопросы по тегам