I am attempting to connect to Postgres once, outside of my Spock application, but I can't seem to use a Hasql session handle with multiple return types.
My main application is fairly straightforward, but fails to compile.
mainApp :: IO Middleware
mainApp = do
session pgConfig sessConfig $ do
dbHandle <- sessionUnlifter
liftIO $ do
printAHasqlString dbHandle
printAccountCount dbHandle
spockT id (appMiddleware >> appRoutes dbHandle)
If I comment out printAHasqlString or printAccountCount, it compiles and works (both work when running without the other).
printAccountCount :: (MonadBase IO m) => (Session Settings s m Int -> IO Int) -> IO ()
printAHasqlString :: (MonadBase IO m) => (Session Settings s m Text -> IO Text) -> IO ()
printAccountCount does a query returning an Int, and printAHasqlString runs a query for a Text. Both just print the result, and returns an IO ().
But when I attempt to run both queries in the same application, the r type variable in the Session data type gets locked down, and fails to compile with the second one.
Error Message:
src/Main.hs:30:25:
Couldn't match type ‘Text’ with ‘Int’
Expected type: Session Settings s IO Int -> IO Int
Actual type: Session Settings s IO Text -> IO Text
In the first argument of ‘printAccountCount’, namely ‘dbHandle’
In a stmt of a 'do' block: printAccountCount dbHandle
Updated Error
After some help below - I got to a new error:
src/Main.hs:29:24:
Couldn't match type ‘r0’ with ‘a’
because type variable ‘a’ would escape its scope
This (rigid, skolem) type variable is bound by
a type expected by the context: Session Settings s IO a -> IO a
at src/Main.hs:29:7-31
Expected type: Session Settings s IO a -> IO a
Actual type: Session Settings s IO r0 -> IO r0
Relevant bindings include
dbHandle :: Session Settings s IO r0 -> IO r0
(bound at src/Main.hs:27:5)
In the first argument of ‘printAHsqlString’, namely ‘dbHandle’
In a stmt of a 'do' block: printAHsqlString dbHandle
How do I let that type variable remain flexible between calls?
Full (updated) Code: https://gist.github.com/cschneid/4174addefb254a517f35
Since version 0.6.0 there no longer is any
sessionUnlifterfuss. Pool is directly exposed and you can executeSessionon it as many times as you want without any performance penalty.