我们可以使用混凝土的一种方法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 中定义的。