[英]Why adding import `import cats.instances.future._` will result an compilation error for implicit Functor[Future]
The scala code is using cats and works well: Scala代码正在使用cats,并且效果很好:
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"))(_ + "!")
}
But if I add this import: 但是,如果我添加此导入:
import cats.instances.future._
It will report such compilation errors: 它将报告此类编译错误:
Error:(18, 10) could not find implicit value for parameter instance: cats.Functor[scala.concurrent.Future]
Functor[Future].map(Future("hello"))(_ + "!")
Why it happens, and how can I debug it to find reason? 为什么会发生,如何调试它以找到原因? I used all kinds of ways I know, but can't find anything. 我用各种我知道的方法,但找不到任何东西。
The build.sbt
file is: 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"
)
The object cats.implicits
has the FutureInstances
trait as a linear supertype. cats.implicits
对象具有FutureInstances
特性作为线性超类型。 The FutureInstances
has an implicit catsStdInstancesForFuture
method, which produces a Monad[Future]
, which in turn is a Functor[Future]
. FutureInstances
有一个隐式的catsStdInstancesForFuture
方法,该方法产生Monad[Future]
,而Monad[Future]
则是Functor[Future]
。
On the other hand, the object cats.instances.future
also mixes in FutureInstances
, so it again provides an implicit method catsStdInstancesForFuture
, but through another pathway. 另一方面,对象cats.instances.future
也混合在FutureInstances
,因此它再次通过另一种途径提供了隐式方法catsStdInstancesForFuture
。
Now the compiler has two possibilities to generate a Functor[Future]
: 现在,编译器有两种可能性来生成Functor[Future]
:
cats.instances.future.catsStdInstancesForFuture
通过调用cats.instances.future.catsStdInstancesForFuture
cats.implicits.catsStdInstancesForFuture
通过调用cats.implicits.catsStdInstancesForFuture
Since it cannot decide which one to take, it exits with an error message. 由于无法确定要采取哪一个,它会退出并显示一条错误消息。
To avoid that, don't use cats.implicits._
together with cats.instances.future._
. 为避免这种情况,请勿将cats.implicits._
与cats.instances.future._
一起使用。 Either omit one of the imports, or use the 要么忽略其中一种导入,要么使用
`import packagename.objectname.{member1name, member2name}`
to select only those implicits that you need. 仅选择所需的那些隐式。
Adding "-print"
to scalacOptions
could help when debugging implicits: 在调试隐式命令时,向scalacOptions
添加"-print"
会有所帮助:
scalacOptions ++= Seq(
...
"-print",
...
)
It will print out the desugared code with cats.implicits.
它将使用cats.implicits.
打印出已删除的代码cats.implicits.
and cats.instances.
和cats.instances.
-pieces added everywhere. 件随处可见。 Unfortunately, it tends to produce quite a lot of noise. 不幸的是,它往往会产生很多噪音。
The more fundamental reason why this happens is that there is no way to define higher-dimensional-cells (kind-of "homotopies") between the two (equivalent) pathways that lead to a Functor[Future]
. 发生这种情况的更根本原因是,没有办法在导致Functor[Future]
的两个(等效)路径之间定义更高维的细胞(“同型”种类)。 If we had a possibility to tell the compiler that it doesn't matter which path to take , then everything would be much nicer. 如果我们有可能告诉编译器采用哪个路径都没有关系 ,那么一切都会好得多。 Since we can't do it, we have to make sure that there is always only one way to generate an implicit Functor[Future]
. 由于我们无法做到,因此必须确保始终只有一种方法可以生成隐式Functor[Future]
。
The problem is that the instances are imported twice, meaning scalac cannot disambiguate between them and doesn't know which one to use and then fails. 问题在于实例被导入两次,这意味着scalac无法消除它们之间的歧义,也不知道要使用哪个实例,然后失败。
So either you use the implicits._
import or you import specific instances with instances.<datatype>._
, but never both! 因此,要么使用implicits._
import导入,要么使用instances.<datatype>._
导入特定的实例,但绝不要两者都使用!
You can look at a more in depth look of cats imports here: https://typelevel.org/cats/typeclasses/imports.html 您可以在这里更深入地了解猫的进口情况: https : //typelevel.org/cats/typeclasses/imports.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.