I just start coding in Haskell recently and I start getting use of do block. I'm coming from Scala world, and after read a book and some blogs I see that do block was the inspiration of our from comprehension. But still I´m struggling with the arguments that pass in every function as input -> output
Here in my code I'm using scotty http server library to get a request and I'm trying to persist that request in mySQL.
But in this line where I try top get the value from the Maybe to send to the another function to be persisted
user <- (fmap (\user -> insertUser user) maybeUser)
It never compile since the function does not return the expected type
ActionT Text IO (Maybe User)
but
IO User
Here my hole program
createUser :: ActionM ()
createUser = do maybeUser <- getUserParam
-- Persist the user
_ <- persistUser
json maybeUser
getUserParam :: ActionT Text IO (Maybe User)
getUserParam = do requestBody <- body
return (decode requestBody)
persistUser :: Maybe User -> ActionT Text IO (Maybe User)
persistUser _maybeUser = let maybeUser = _maybeUser in do
user <- maybeUser
user <- (fmap (\user -> insertUser user) maybeUser)
return maybeUser
insertUser :: User -> IO User
insertUser _user = let user = _user in do
conn <- createConnection
status <- execute conn insertUserQuery [MySQLInt32 (intToInt32 $ getUserId user), MySQLText "hello_haskell_world"]
return user
Let's consider the following function:
persistUser :: Maybe User -> ActionT Text IO (Maybe User)
A value of type Maybe User
is passed as an argument, and we need this user to be inserted into database. In order to do that, we can use (<$>)
(or fmap
) function as:
insertUser <$> maybeUser
The resulting type is: Maybe (IO User)
. Now we need to lift this type to ActionT Text IO (Maybe User)
somehow.
Web.Scotty.Trans
has a liftAndCatchIO function (also available in Web.Scotty
module), which mostly does what we need, but it accepts IO a
as an argument, so we need to "swap" Maybe
and IO
. Let's find a function for this. So sequence does what we need.
As a result, we have the following implementation of persistUser
function:
persistUser maybeUser =
liftAndCatchIO $ sequence $ insertUser <$> maybeUser