[英]Why adding import `import cats.instances.future._` will result an compilation error for implicit Functor[Future]
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"))(_ + "!")
}
但是,如果我添加此导入:
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
特性作为线性超类型。 FutureInstances
有一个隐式的catsStdInstancesForFuture
方法,该方法产生Monad[Future]
,而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}`
仅选择所需的那些隐式。
在调试隐式命令时,向scalacOptions
添加"-print"
会有所帮助:
scalacOptions ++= Seq(
...
"-print",
...
)
它将使用cats.implicits.
打印出已删除的代码cats.implicits.
和cats.instances.
件随处可见。 不幸的是,它往往会产生很多噪音。
发生这种情况的更根本原因是,没有办法在导致Functor[Future]
的两个(等效)路径之间定义更高维的细胞(“同型”种类)。 如果我们有可能告诉编译器采用哪个路径都没有关系 ,那么一切都会好得多。 由于我们无法做到,因此必须确保始终只有一种方法可以生成隐式Functor[Future]
。
问题在于实例被导入两次,这意味着scalac无法消除它们之间的歧义,也不知道要使用哪个实例,然后失败。
因此,要么使用implicits._
import导入,要么使用instances.<datatype>._
导入特定的实例,但绝不要两者都使用!
您可以在这里更深入地了解猫的进口情况: https : //typelevel.org/cats/typeclasses/imports.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.