scala - 为什么添加 import `import cats.instances.future._` 会导致隐式 Functor[Future] 编译错误

标签 scala compilation future functor scala-cats

Scala 代码正在使用猫并且运行良好:

import cats.implicits._
import cats.Functor
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

object Hello extends App {

  Functor[Future].map(Future("hello"))(_ + "!")

}

但是如果我添加这个导入:
import cats.instances.future._

它会报这样的编译错误:
 Error:(18, 10) could not find implicit value for parameter instance: cats.Functor[scala.concurrent.Future]
   Functor[Future].map(Future("hello"))(_ + "!")

为什么会发生,我该如何调试以找出原因?我用了我知道的各种方法,但找不到任何东西。
build.sbt文件是:
name := "Cats Implicit Functor of Future Compliation Error Demo"

version := "0.1"

organization := "org.my"

scalaVersion := "2.12.4"

sbtVersion := "1.0.4"

libraryDependencies ++= Seq(
  "org.typelevel" %% "cats-core" % "1.0.1"
)

最佳答案

对象 cats.implicits FutureInstances trait作为线性父类(super class)型。 FutureInstances有一个隐含的 catsStdInstancesForFuture方法,产生一个 Monad[Future] ,这又是一个 Functor[Future] .

另一方面,对象 cats.instances.future 也混入 FutureInstances ,所以它再次提供了一个隐式方法 catsStdInstancesForFuture ,而是通过另一条途径。

现在编译器有两种可能生成 Functor[Future] :

  • 通过调用 cats.instances.future.catsStdInstancesForFuture
  • 通过调用 cats.implicits.catsStdInstancesForFuture

  • 由于它无法决定采用哪一个,因此它会以错误消息退出。

    为避免这种情况,请不要使用 cats.implicits._连同cats.instances.future._ .要么省略其中一个导入,要么使用
    `import packagename.objectname.{member1name, member2name}`
    

    仅选择您需要的那些隐式。

    添加 "-print"scalacOptions在调试隐式时可能会有所帮助:
    scalacOptions ++= Seq(
      ...
      "-print",
      ...
    )
    

    它将用 cats.implicits. 打印出脱糖代码和 cats.instances. - 到处都添加了件。不幸的是,它往往会产生相当多的噪音。

    发生这种情况的更根本原因是,无法定义导致 Functor[Future] 的两个(等效)途径之间的高维细胞(某种“同伦”)。 .如果我们有可能告诉编译器走哪条路无关紧要,那么一切都会好得多。既然我们做不到,我们必须确保总是只有一种方法可以生成隐式 Functor[Future] .

    关于scala - 为什么添加 import `import cats.instances.future._` 会导致隐式 Functor[Future] 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48886068/

    相关文章:

    ios - 在后台线程中执行组合 future 不起作用

    scala - Actor 模型是否仅限于特定语言?

    java - 如何在java中以单个命令编译和运行

    java - 打破 CompletableFuture 的流程

    c++ - 需要沙盒应用程序,该应用程序从在线不受信任的来源编译 C++ 模块

    c++ - 编译 C++ 应用程序,以便它们也可以在其他计算机上工作

    Flutter Future<bool> 与 bool 类型

    scala - 为什么全局 ExecutionContext 不是 future block 中的默认参数?

    java - "Could not find main method from given launch configuration"使用Java+Scala+Slick2D时

    scala - 强制Redis超时