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/