尝试使用持久性时没有 Control.Monad.Logger.MonadLogger 的实例
Posted
技术标签:
【中文标题】尝试使用持久性时没有 Control.Monad.Logger.MonadLogger 的实例【英文标题】:No instance for Control.Monad.Logger.MonadLogger when attempting to use persistent 【发布时间】:2014-01-17 20:29:14 【问题描述】:我正在使用 scotty
和 persistent
构建一个 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
,这也将迫使我使用许多其他软件包的旧版本,包括scotty
和persistent
,我不这样做'不想那样做。另一个答案建议使用runNoLoggingT
,我无法正常工作。我不知道把它放在哪里进行类型检查。
【问题讨论】:
【参考方案1】:runNoLoggingT
有类型
runNoLoggingT :: NoLoggingT m a -> m a
只要上面的m
是MonadIO
的一个实例,它就是一个有效的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 构造函数中以上是关于尝试使用持久性时没有 Control.Monad.Logger.MonadLogger 的实例的主要内容,如果未能解决你的问题,请参考以下文章