持久化SqlPersistT与Servants处理程序的组合

时间:2018-08-03 19:39:18

标签: haskell monad-transformers

我正在尝试定义一个辅助函数,该函数将允许我使用在Reader monad中运行时提供的连接池来运行查询。我想定义一个函数,将提取池中的asks部分,如下所示:

type Config = Config { getPool :: ConnectionPool }

type App = ReaderT Config

runQuery :: MonadBaseControl IO m => SqlPersistT m a -> App m a
runQuery query =
  asks getPool >>= lift . runSqlQuery

尽管我在编译它时遇到了麻烦...我可能已经发誓这段代码曾在以前的项目中使用过,但低估了它的工作。当我查看Handler({{1}中我想要的m)的定义时,它们和App m都不同。看来runSqlQuery有一个Handler的实例,而MonadBaseControl IO m使用了runSqlQuery,但是,回头看一下添加MonadUnliftIO之前的更改,{{ 1}}使用了MonadUnliftIO ...这是我以前的代码在这种情况下起作用的原因。

所以我想我的问题是,如何更改runSqlQuery的实现以支持MonadBaseControl IO m现在基于runQuery的事实?我浏览了runSqlQuery提供的功能(即MonadUnliftIO),但一直想不出一种使类型合适的方法。

2 个答案:

答案 0 :(得分:0)

此代码以persistent-2.8.2编译:

runQuery :: MonadUnliftIO m => ReaderT SqlBackend m b -> App m b
runQuery query =
    asks getPool >>= lift . runSqlPool query

答案 1 :(得分:0)

这似乎是MonadUnliftIO的故意设计决定,在“限制”下查看https://www.stackage.org/package/unliftio处的自述文件,它表明它不支持“具有多个出口点的变压器(例如,ExceptT )”,而Servant的HandlerExceptT的包装。我可能只需要找到另一种编写此代码的方式。