I am following this tutorial which uses scotty with persistent to create a simple API .
However, I am trying to create a simple api with scotty and mysql simple library.
Now I am stuck at one point in code .
In the below code I am not able to convert getUser function to type "ActionT Error ConfigM" because of which my code is failing.
Can anyone help me with understanding how I can convert getUser function to achieve needed type signature?
Code
type Error = Text
type Action = ActionT Error ConfigM ()
config :: Config
config = Config
{ environment = Development
,db1Conn = connect connectionInfo
}
main :: IO ()
main = do
runApplication config
runApplication :: Config -> IO ()
runApplication c = do
o <- getOptions (environment c)
let r m = runReaderT (runConfigM m) c
scottyOptsT o r application
application :: ScottyT Error ConfigM ()
application = do
e <- lift (asks environment)
get "/user" getTasksA
getTasksA :: Action
getTasksA = do
u <- getUser
json u
getUser :: IO User
getUser = do
e <- asks environment
conn <- db1Conn config
[user]<- query_ conn "select login as userId, email as userEmail from member limit 1"
return user
Error
• Couldn't match type ‘IO’ with ‘ActionT Error ConfigM’
Expected type: ActionT Error ConfigM User
Actual type: IO User
• In a stmt of a 'do' block: u <- getUser
In the expression:
do { u <- getUser;
json u }
In an equation for ‘getTasksA’:
getTasksA
= do { u <- getUser;
json u }
You left out plenty of code (imports and pragmas and the definitions of
User
, please include that next time - see MCVE.But now to your question:
I would change the
Action
type to the followingthen
getTasksA
has the following type signature(alternatively you can write this as
getTasksA = getUser >>= json
)and
getUser
A few remarks
[user] <- liftIO $ query ..
is a bad idea - if no user is found this crashes your application - try to write total functions and pattern matches. Better return aMaybe User
.if you can wrap your head around it, rather use
persistent
than writing your SQL queries by hand - this is quite error prone, especially when refactoring, just imagine renaminguserId
touserID
.you
ask
several times for theenvironment
but then don't use it. Compile with-Wall
or even-Werror
to get a warning or even elevate warnings to compile errors (which is a good idea for production settings.