Leo*_*nti 5 scala scala-cats doobie cats-effect
我正在尝试在使用 Doobie 将用户插入数据库的同一事务中发送电子邮件。
我知道我可以举IO到ConnectionIO通过使用Async[ConnectionIO].liftIO(catsIO)其中catsIO: IO[String]
但在我的代码,我不上工作IO,我使用F与约束,例如F[_]: Async
于是我可以代替F我自己的单子进行测试。
是否可以在不直接使用类型的情况下以某种方式提升F[String]进入? ConnectionIO[String]IO
这是我为 IO 类型找到的答案:Doobie and DB access composition within 1 transaction
Cats 有一种叫做 FunctionK 的东西,它是一种自然转换。
我这样做了:
在世界之巅,一切都在这里建造,你将需要这个
val liftToConnIO: FunctionK[IO, ConnectionIO] = LiftIO.liftK[ConnectionIO]
Run Code Online (Sandbox Code Playgroud)
在需要从 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 ()
}
Run Code Online (Sandbox Code Playgroud)
(您可能需要 F 和 G 上的上下文边界(同步?))