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

如何在Scala Cats Effect中用类的封闭效果类型实现doobie LogHandler

问题:在doobie中使用泛型效果类型实现LogHandler

我有如下实现代码:

final class MyServiceImpl[M[_]: Async](dbCfg: DBConfig)(implicit ec: Scheduler) extends MyService[M] {
  ......
  ......
  ......
  ......
}

该类内部有一些使用doobie执行数据库SQL查询的方法。测试过程中我需要记录这些查询,而doobie提供了实现LogHandler[M[_]] trait的方案来完成此需求。

根据doobie文档,我可以在MyServiceImpl中编写如下代码:

val printSqlLogHandler: LogHandler[IO] = new LogHandler[IO] {
  def run(logEvent: LogEvent): IO[Unit] = 
    IO { 
      println(logEvent.sql)
    }
}

但该示例使用了IO类型,我希望改用MyServiceImpl实例化时指定的效果类型,请问该如何实现?


解决方案

直接利用类上已有的Async[M]上下文约束,将IO替换为泛型M[_],借助Async[M].delay方法创建对应效果类型的逻辑:

val printSqlLogHandler: LogHandler[M] = new LogHandler[M] {
  def run(logEvent: LogEvent): M[Unit] = 
    Async[M].delay { 
      println(logEvent.sql)
    }
}

关键说明

  • 类定义时的[M[_]: Async]约束保证了Async[M]实例在类内部可用
  • Async[M].delay的作用和IO.delay一致,能把同步副作用(此处为println)包装成指定的泛型效果类型M
  • 最终printSqlLogHandler的类型为LogHandler[M],可以直接和类中使用泛型M的doobie查询配合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:55:59