为什么导入类型 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 withcats.syntax.all._
and delete anycats.instances
imports. You don't have to make this change to use Cats 2.2.x, though, since this release doesn't remove anything. Importingcats.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 ownOrder
andPartialOrder
type classes to the standard library'sOrdering
andPartialOrdering
. 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