我一直在尝试通过将mtl 与persistent结合使用来构建项目,从而对mtl有一个很好的理解。
该项目的一个模块具有使用insertMany_的功能
service
:: (MonadReader ApplicationConfig m, MonadIO m) =>
ReaderT SqlBackend (ExceptT ApplicationError m) ()
service = insertMany_ =<< lift talkToAPI
这里talkToAPI
可能会失败,因此响应包含在 中ExceptT
,它的类型是
ExceptT ApplicationError m [Example]
简而言之,service
的工作是与 API 对话,解析响应并将insertMany_
响应存储到数据库中。
实际的存储操作由withPostgresqlConn处理
withPostgresqlConn
:: (MonadUnliftIO m, MonadLogger m) =>
ConnectionString -> (SqlBackend -> m a) -> m a
runReaderT
在我的函数上使用service
会产生
ghci> :t runReaderT service
ghci> (MonadReader ApplicationConfig m, MonadIO m) =>
SqlBackend -> ExceptT ApplicationError m ()
所以要处理这个我相信我需要runExceptT
像这样使用
runService :: ConnectionString -> IO ()
runService connStr = either print return
=<< runStdLoggingT (runExceptT $ withPostgresqlConn connStr $ runReaderT service)
但我得到这两个错误
• No instance for (MonadUnliftIO (ExceptT ApplicationError IO))
arising from a use of ‘withPostgresqlConn’
• No instance for (MonadReader ApplicationConfig IO)
arising from a use of ‘service’
这里可能是什么问题?我可能有一个错误,但我不确定在哪里寻找。