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