为什么导入类型 class 实例不再需要导入 cats.implicits._?

Why is import cats.implicits._ no longer necessary for importing type class instances?

在猫 2.1.x 中类型 class 实例被引入 import cats.implicits._

范围
scala> import cats.Show
import cats.Show

scala> Show[Int].show(42)
<console>:13: error: could not find implicit value for parameter instance: cats.Show[Int]
       Show[Int].show(42)
           ^

scala> import cats.implicits._
import cats.implicits._

scala> Show[Int].show(42)
res1: String = 42

但是在 Cats 2.2.0 中它可以在没有 import cats.implicits._ 的情况下工作,例如

scala> import cats.Show
import cats.Show

scala> Show[Int].show(42)
val res0: String = 42

发生了什么变化,从现在开始我们应该如何使用导入?

在 2.1.x 中,类型 类 的实例在单独的对象中定义,因此为了在范围(本地范围)内,必须导入它们

object implicits extends instances.AllInstances with ...

trait AllInstances extends AnyValInstances with ...

trait AnyValInstances extends IntInstances with ...

trait IntInstances extends cats.kernel.instances.IntInstances {
  implicit val catsStdShowForInt: Show[Int] = Show.fromToString[Int]
}

在 2.2.0 中,类型 类 的实例在伴生对象中定义,因此它们自动处于作用域(隐式作用域)中,无需导入

object Show extends ScalaVersionSpecificShowInstances with ShowInstances {
  ...
  implicit def catsShowForInt: Show[Int] = cats.instances.int.catsStdShowForInt
  ...
}

发行说明https://github.com/typelevel/cats/releases/tag/v2.2.0

In most cases all that's necessary to switch to using the new implicit scope instances is to replace cats.implicits._ imports with cats.syntax.all._ and delete any cats.instances imports. You don't have to make this change to use Cats 2.2.x, though, since this release doesn't remove anything. Importing cats.implicits._ will do exactly the same thing on Cats 2.1.x and 2.2.x, since imported instances have higher priority than implicit scope. You just won't see improvements in compile times.

There is one exception to this rule. The cats.implicits package provides implicit conversions from Cats's own Order and PartialOrder type classes to the standard library's Ordering and PartialOrdering. This conversion is not available in implicit scope, because it would be a bad idea for Cats to put instances of type classes it doesn't own into scope for types that it doesn't own (and also because it's not possible).

Where does Scala look for implicits?

https://docs.scala-lang.org/tutorials/FAQ/finding-implicits.html