Hi I a pretty new to Haskell and I have been working on a small web application with Scotty and Sqlite.
I am having trouble performing Sqlite operations inside the Scotty Actions. I kind of understanding the two libraries when used in isolation.
Here is the MVP of my code
-- imports ...
routes :: ScottyM ()
routes = do
post "data/:id" $ do
id <- param "id"
-- HERE IS WHERE I GET CONFUSED
-- This is what I want to do
db <- open "store.db"
exec db "INSERT INTO Store (id, value) VALUES (" <> id <> ", 'Test Value');" -- I know there is SQL Injection here I will learn about parameterized queries in haskell next
close db
-- END THE PART I AM CONFUSED BY
text $ "created a record with " <> id <> " id."
main :: IO()
scotty 3000 routes
So as you can see I am still stuck thinking too imperatively. I know the type of post is ActionM () -> ScottyM () and I know the type of close db is IO ()
So what I think I need is a composite function that goes ActionM () -> IO () -> ScottyM () I am just not sure how to write this.
Is this on the right track?
Any and all advice is greatly appreciated.
Monads stack (technically, Monad Transformers stack). Which means that in some advanced monads it is possible to do thing with more basic monads further down the stack.
The lift
function will take a function from one level down the stack and "lift" it into the current one. the liftIO
function will take a generic IO function and lift it into the current context. (IO, if it is included, is always the bottom of the Monad Transformer stack)
Real World Haskell and the Haskell Wiki both have good chapters on Monad Transformers.