简体   繁体   English

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

[英]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]

  • by invoking cats.instances.future.catsStdInstancesForFuture 通过调用cats.instances.future.catsStdInstancesForFuture
  • by invoking 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM