0

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
paul
  • 12,873
  • 23
  • 91
  • 153

1 Answers1

2

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
augustss
  • 22,884
  • 5
  • 56
  • 93
Igor Drozdov
  • 14,690
  • 5
  • 37
  • 53