【问题标题】:No instance for Control.Monad.Logger.MonadLogger when attempting to use persistent尝试使用持久性时没有 Control.Monad.Logger.MonadLogger 的实例
【发布时间】:2014-01-17 20:29:14
【问题描述】:

我正在使用 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

我收到此错误消息:

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

我找到了this 的问题,但接受的答案是使用旧版本的monad-logger,这也将迫使我使用许多其他软件包的旧版本,包括scottypersistent,我不这样做'不想那样做。另一个答案建议使用runNoLoggingT,我无法正常工作。我不知道把它放在哪里进行类型检查。

【问题讨论】:

    标签: database haskell web-applications logging persistent


    【解决方案1】:

    runNoLoggingT 有类型

    runNoLoggingT :: NoLoggingT m a -> m a
    

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

    SqlPersist (ResourceT IO)
                ResourceT IO
                          IO
    

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

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

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

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

    【讨论】:

    • 我猜你必须将值包装在 NoLoggingT 构造函数中
    猜你喜欢
    • 2013-03-13
    • 2015-01-05
    • 2011-11-01
    • 2013-08-08
    • 2013-02-17
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多