You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中提取liftIO与runSql为独立函数的实现方案

Persist + Servant 代码复用问题解决

问题背景

使用Persist和Servant开发时,在某模块中定义了以下类型别名与数据库执行函数:

-- 便捷类型别名
type DbAction m a = ReaderT SqlBackend m a

-- 使用连接池运行数据库查询
runSql :: DbAction (NoLoggingT (ResourceT IO)) a -> ConnectionPool -> IO a
runSql = runSqlPersistMPool

但在另一个模块的Servant API实现中,出现了大量重复代码:

postUser :: UserCreate -> Handler Text
    postUser user = liftIO $ flip runSql pool $ do
      storeUser user

    getUser :: PathUserId -> Handler (Maybe User)
    getUser uid = liftIO $ flip runSql pool $ do
      fetchUser $ extractUserId uid

希望将重复的liftIO $ flip runSql pool $ ...逻辑提取为独立函数以减少冗余,但尝试过程中遇到阻碍。

失败的尝试

曾尝试以下实现,但SqlPersistT仅存在于Sqlite包中,引入了不必要的依赖:

runDbAction :: SqlPersistT IO a -> Handler a
runDbAction action = liftIO $ flip runSql pool $ action

最终解决方案

改用核心persistent包提供的SqlPersistM类型(无需额外依赖),实现通用的数据库动作执行函数:

runDbAction :: SqlPersistM a -> Handler a
    runDbAction action = liftIO $ runSql action pool

内容的提问来源于stack exchange,提问作者igr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:54:54