在 http4s 版本 19.0.0 中找不到 ContextShift[cats.effect.IO] 的隐式值
Cannot find an implicit value for ContextShift[cats.effect.IO] in http4s version 19.0.0
我有一个使用 ciris 进行配置管理的 http4s 项目。
项目在 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
感谢任何帮助。
有several popular usages of implicit
,其中之一是传递一些"context"信息。您看到的代码是这种用法的经典示例。
当您执行 "timeout" 时,您需要决定两件事:
- 主要工作 运行 的位置(在哪个线程上)
- 在 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
}
它应该可以编译。
我有一个使用 ciris 进行配置管理的 http4s 项目。
项目在 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
感谢任何帮助。
有several popular usages of implicit
,其中之一是传递一些"context"信息。您看到的代码是这种用法的经典示例。
当您执行 "timeout" 时,您需要决定两件事:
- 主要工作 运行 的位置(在哪个线程上)
- 在 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
}
它应该可以编译。