Doobie - 将任意效果提升到 ConnectionIO 中

2024-04-11

我正在尝试在使用 Doobie 将用户插入数据库的同一事务中发送电子邮件。
我知道我可以举起IO into ConnectionIO通过使用Async[ConnectionIO].liftIO(catsIO) where catsIO: IO[String]
但在我的代码中我不进行操作IO, I use F有约束条件,例如F[_]: Async那么我可以替换F用我自己的 monad 进行测试。

是否有可能以某种方式举起F[String] into ConnectionIO[String]不使用IO直接输入?

这是我找到的 IO 类型的答案:1 个事务内的 Doobie 和 DB 访问组合 https://stackoverflow.com/questions/50472904/doobie-and-db-access-composition-within-1-transaction


Cats 有一个叫做 FunctionK 的东西,这是一种自然的转换。

我这样做了:

在世界之巅,一切都已建成,你将需要这个

val liftToConnIO: FunctionK[IO, ConnectionIO] = LiftIO.liftK[ConnectionIO]

在需要从 F[String] 转换为 G[String] 的类中(当您构造所有内容时,F 将是 IO,G 将是 ConnectionIO),您可以通过liftToConnIO并在需要时使用它将 F[A] 转换为 G[A]。

不想抽象 IO 和 ConnectionIO 的类可以通过 FunctionK 来完成提升:

class Stuff[F[_], G[_]](emailer: Emailer[F], store: Store[G], liftToG: FunctionK[F, G]) {

  def sendEmail: G[Unit] =
    for {
      _ <- doDatabaseThingsReturnStuffInG
      _ <- liftToG(emailer.sendEmail)
      _ <- doMoreDatabaseThingsReturnStuffInG
     } yield ()

}

(您可能需要 F 和 G 上的上下文边界(同步?))

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Doobie - 将任意效果提升到 ConnectionIO 中 的相关文章

随机推荐