如何在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
相关产品推荐
相关产品推荐

