我有一些返回 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)

其中 ioConcurrentEffectEffect[IO] 实例。

似乎所有的好东西都定义在 org.http4s.syntax.AllSyntax trait 中。

关于scala - 如何使用 http4s 将猫 IO 转换为 Effect,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49955558/

10-13 09:00