Question

I'm building a web app using scotty and persistent and having some troubles compiling. This is my code:

runDb :: SqlPersist (ResourceT IO) a -> IO a
runDb query = runResourceT . withSqliteConn "dev.app.sqlite3" . runSqlConn $ query

readMessage :: KeyBackend (PersistEntityBackend Post) Post -> IO (Maybe Post)
readMessage postID = runDb $ get postID

And I get this error message:

Message.hs:30:30:
No instance for (Control.Monad.Logger.MonadLogger IO)
  arising from a use of `get'
Possible fix:
  add an instance declaration for
  (Control.Monad.Logger.MonadLogger IO)
In the second argument of `($)', namely `get postID'
In the expression: runDb $ get postID
In an equation for `readMessage':
    readMessage postID = runDb $ get postID

I found this question, but the accepted answer is use an old version of monad-logger which would also force me to use old versions of many other packages, scotty and persistent included, and I don't want to do that. The other answer recommends using runNoLoggingT, which I was unable to get working. I couldn't figure out where to put it to get it to typecheck.

Was it helpful?

Solution

runNoLoggingT has the type

runNoLoggingT :: NoLoggingT m a -> m a

and it's a valid MonadLogger so long as m above is an instance of MonadIO. All of the following stacks are instances of MonadIO

SqlPersist (ResourceT IO)
            ResourceT IO
                      IO

So all of the following stacks are valid instances of MonadLogger

NoLoggingT (SqlPersist (ResourceT IO))
SqlPersist (NoLoggingT (ResourceT IO))
SqlPersist (ResourceT (NoLoggingT IO))

I'd recommend the third, then we just edit

runDb :: SqlPersist (ResourceT (NoLoggingT IO)) a -> IO a
runDb = runNoLoggingT 
      . runResourceT 
      . withSqliteConn "dev.app.sqlite3" 
      . runSqlConn
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top