我有一些返回 IO 的代码,但我需要在 http4s 中使用 Effect。
import cats.effect.{Effect, IO}
class Service[F[_]: Effect] extends Http4sDsl[F] {
val service: HttpService[F] = {
HttpService[F] {
case GET -> Root =>
val data: IO[String] = getData()
data.map(d => Ok(d))
}
}
}
给
[error] found : cats.effect.IO[F[org.http4s.Response[F]]]
[error] required: F[org.http4s.Response[F]]
[error] data.map(d => Ok(d))
[error] ^
最佳答案
我们可以使用具体的 IO[A]
绕过的一种方法是使用 LiftIO[F]
:
class Service[F[_]: Effect] extends Http4sDsl[F] {
val service: HttpService[F] = {
HttpService[F] {
case GET -> Root =>
getData().liftIO[F].flatMap(Ok(_))
}
}
}
LiftIO
lifts 将提升: IO[A] => F[A]
,但这会产生 F[F[Response[F]
。为了编译,我们将 flatten
放在 F
上,因为由于我们的 Monad
上下文边界要求,它在猫中有一个 FlatMap
(或 Effect
)实例。如果我们想要更多细节,这是
-Xprint:typer
结果:cats.implicits.catsSyntaxFlatten[F, org.http4s.Response[F]](
cats.effect.LiftIO.apply[F](Service.this.evidence$1)
.liftIO[F[org.http4s.Response[F]]](
data.map[F[org.http4s.Response[F]]](
((d: String) => Service.this.http4sOkSyntax(Service.this.Ok)
.apply[String](d)(Service.this.evidence$1,
Service.this.stringEncoder[F](
Service.this.evidence$1, Service.this.stringEncoder$default$2[F]))))))(Service.this.evidence$1).flatten(Service.this.evidence$1)
在世界末日,当你想要给出一个具体的效果时,例如
Service[IO]
,我们得到:val serv: Service[cats.effect.IO] =
new Service[cats.effect.IO]()(effect.this.IO.ioConcurrentEffect)
其中
ioConcurrentEffect
是 Effect[IO]
实例。似乎所有的好东西都定义在
org.http4s.syntax.AllSyntax
trait 中。关于scala - 如何使用 http4s 将猫 IO 转换为 Effect,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49955558/