尝试使用持久性时,没有Control.Monad.Logger.MonadLogger的实例

Dre*_*rew 11 database logging haskell web-applications persistent

我正在构建一个使用scottypersistent编译的麻烦的Web应用程序.这是我的代码:

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
Run Code Online (Sandbox Code Playgroud)

我收到此错误消息:

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
Run Code Online (Sandbox Code Playgroud)

我发现了这个问题,但接受的答案是使用旧版本monad-logger也会迫使我使用许多其他软件包的旧版本,scotty并且persistent包括在内,我不想这样做.另一个答案建议使用runNoLoggingT,我无法工作.我无法弄清楚要把它放到什么样的地方.

J. *_*son 10

runNoLoggingT 有类型

runNoLoggingT :: NoLoggingT m a -> m a
Run Code Online (Sandbox Code Playgroud)

MonadLogger只要m上面是一个实例,它就是有效的MonadIO.所有以下堆栈都是实例MonadIO

SqlPersist (ResourceT IO)
            ResourceT IO
                      IO
Run Code Online (Sandbox Code Playgroud)

所以以下所有堆栈都是有效的实例 MonadLogger

NoLoggingT (SqlPersist (ResourceT IO))
SqlPersist (NoLoggingT (ResourceT IO))
SqlPersist (ResourceT (NoLoggingT IO))
Run Code Online (Sandbox Code Playgroud)

我推荐第三个,然后我们只是编辑

runDb :: SqlPersist (ResourceT (NoLoggingT IO)) a -> IO a
runDb = runNoLoggingT 
      . runResourceT 
      . withSqliteConn "dev.app.sqlite3" 
      . runSqlConn
Run Code Online (Sandbox Code Playgroud)