I'm working on Haskell code in the Snap framework. Everything works but now I need to clean up some code. However, after a few attempts, it seems I just have more code. Maybe anyone can give me some pointers?
This was my initial code. The thing is, I pattern match against a Maybe
value which seems to me is very wrong. So I wanted to get that out of the way. But then the next line would get a Maybe
value so I had to change that..
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"
Eventually I came to this:
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"
The problem with this is that I have a feeling I shouldn't do a pattern match against the Nothing
either. I'm in a do
, so there should be something here. And the other thing is, I have a do
in register
as well. Any pointers are appreciated.
There's nothing wrong with your new code. Part of the reason that it's longer than the original is that you are handling the Nothing
case, which you weren't doing originally (so your new code is safer). If you wanted to neaten it up a bit, you could write it as
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"
where I've used the function maybe
from Data.Maybe
to remove the need to explicitly handle the Just
or Nothing
values. This function is just defined as
maybe :: b -> (a -> b) -> Maybe a -> b
maybe b _ Nothing = b
maybe _ f (Just a) = f a