Scala 杜比-将任意效果提升到康涅狄格州
我试图在将用户插入Doobie数据库的同一事务中发送电子邮件。Scala 杜比-将任意效果提升到康涅狄格州,scala,scala-cats,cats-effect,doobie,Scala,Scala Cats,Cats Effect,Doobie,我试图在将用户插入Doobie数据库的同一事务中发送电子邮件。 我知道我可以通过使用Async[ConnectionIO].liftIO(catsIO)将IO提升到ConnectionIO,其中catsIO:IO[String] 但是在我的代码中,我不在IO上操作,我使用带有约束的F,例如F[\uuuz]:Async 这样我就可以用自己的monad替换F,进行测试 是否可以不直接使用IO类型,以某种方式将F[String]提升到ConnectionIO[String]中 以下是我为IO类型找到的
我知道我可以通过使用
Async[ConnectionIO].liftIO(catsIO)
将IO
提升到ConnectionIO
,其中catsIO:IO[String]
但是在我的代码中,我不在
IO
上操作,我使用带有约束的F
,例如F[\uuuz]:Async
这样我就可以用自己的monad替换F
,进行测试
是否可以不直接使用IO
类型,以某种方式将F[String]
提升到ConnectionIO[String]
中
以下是我为IO类型找到的答案:是的,您可以轻松地将
F[String]
实例化为ConnectionIO[String]
。
给定如下函数:
def foo[F[_]: Async]: F[String] = ...
要在Toconnectiono
中实例化,只需执行以下操作:
def fooCIO: ConnectionIO[String] = foo[ConnectionIO]
猫有一种叫做FunctionK的东西,这是一种自然的转变 我这样做: 在世界之巅,一切都建立在那里,你将需要这个
val liftToConnIO: FunctionK[IO, ConnectionIO] = LiftIO.liftK[ConnectionIO]
在需要从F[String]转换为G[String]的类中(构建所有内容时,F将是IO,G将是ConnectionIO),您可以传递liftToConnIO
,并在需要时使用它将F[A]转换为G[A]
不想通过IO和Connectiono进行抽象的类可以通过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 ()
}
class-Stuff[F],G[F](emailer:emailer[F],store:store[G],liftToG:FunctionK[F,G]){
def发送电子邮件:G[单位]=
为了{
_Channing答案的变体
class-Stuff[F]:Effect,G[\u]:LiftIO](emailer:emailer[F],store:store[G]){
def发送电子邮件:G[单位]=
为了{
_