代码之家  ›  专栏  ›  技术社区  ›  user51

在http4s版本19.0.0中找不到ContextShift[cats.effect.IO]的隐式值

  •  0
  • user51  · 技术社区  · 6 年前

    我有一个http4s项目,它使用 ciris 用于配置管理。

    该项目位于github here .

    libraryDependencies ++= Seq(
      "is.cir" %% "ciris-cats",
      "is.cir" %% "ciris-cats-effect",
      "is.cir" %% "ciris-core",
      "is.cir" %% "ciris-enumeratum",
      "is.cir" %% "ciris-refined"
    ).map(_ % "0.12.1")
    
    libraryDependencies ++= Seq(
      "org.http4s" %% "http4s-dsl",
      "org.http4s" %% "http4s-blaze-server"
    ).map(_ % "0.18.18")
    
    libraryDependencies ++= Seq(
      "com.ovoenergy" %% "ciris-kubernetes" % "0.5",
      "org.typelevel" %% "kittens" % "1.2.0",
      "eu.timepit" %% "refined-cats" % "0.9.3"
    )
    

    当我编译我的项目时,我得到以下错误 here

        [info] Compiling 12 Scala sources to /Users/rajkumar.natarajan/Documents/Coding/OS/ciris-example/target/scala-2.12/classes ...
        [error] /Users/rajkumar.natarajan/Documents/Coding/OS/ciris-example/src/main/scala/is/cir/example/application/Http4sApi.scala:24:68: Cannot find an implicit value for ContextShift[cats.effect.IO]:
        [error] * import ContextShift[cats.effect.IO] from your effects library
        [error] * if using IO, use cats.effect.IOApp or build one with cats.effect.IO.contextShift
        [error]   implicit val ioConcurrentEffect: Concurrent[IO] = cats.effect.IO.ioConcurrentEffect
        [error]                                                                    ^
        [error] /Users/rajkumar.natarajan/Documents/Coding/OS/ciris-example/src/main/scala/is/cir/example/application/Http4sApi.scala:43:69: type mismatch;
        [error]  found   : (ec: scala.concurrent.ExecutionContext, sc: java.util.concurrent.ScheduledExecutorService)cats.effect.Timer[cats.effect.IO] <and> (ec: scala.concurrent.ExecutionContext)cats.effect.Timer[cats.effect.IO]
        [error]  required: cats.effect.Timer[cats.effect.IO]
        [error]         Timeout(finite)(service)(ioConcurrentEffect, cats.effect.IO.timer)
        [error]                                                                     ^
    

    原因是我缺少函数所需的隐式参数 here use cats.effect.IOApp or build one with cats.effect.IO.contextShift 但是找不到 cats.effect.IOApp cats.effect.IO.contextShift

    感谢您的帮助。

    1 回复  |  直到 6 年前
        1
  •  6
  •   Ben Hutchison    4 年前

    several popular usages of implicit 其中之一就是传递一些“上下文”信息。您看到的代码就是这种用法的经典示例。

    当您执行“超时”时,您需要决定两件事:

    • 在JVM世界中,计时器将在哪里(哪个线程上)启动(与JavaScript不同),没有标准的计时器。

    这些参数的重要之处在于,一方面,它们对工作至关重要,但另一方面,它们只支持主要参数。另一件事是,您可能只希望有一个(或很少)全局对象,您可以在任何地方使用这些对象。这就是它们成为上下文的原因,也是它们被隐式传递的原因。

    现在,您可以选择从何处获取它们:

    • 创建自己的实例

    这个选择不是一个简单的设计决策,它取决于您将如何使用API。通常正确的选择是第一个——让它们成为你的背景。通过这种方式,您允许调用者以其希望的方式设置上下文(例如,应该) Timer Concurrent 使用相同的线程池还是不同的线程池?)。有时,创建自己的独立上下文是可以的。或者将从外部接收到的另一个上下文包装成特定于您的内容。

    假设您希望将外部上下文包装在 Http4sApi

    final case class Http4sApi()(implicit executionContext: ExecutionContext) extends HttpApiAlg[IO] {
      // create IO-specific context from the executionContext
      private implicit val cs = IO.contextShift(executionContext)
      private implicit val timer = IO.timer(executionContext)
    

    那你就可以直接写了

    def withTimeout(timeout: Duration)(service: HttpService[IO]): HttpService[IO] = timeout match {
        case finite: FiniteDuration => Timeout(finite)(service)
        case _                      => service
    }
    

    推荐文章