简体   繁体   中英

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

In Cats 2.1.x type class instances were brought in scope with 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

however in Cats 2.2.0 it works without import cats.implicits._ for example

scala> import cats.Show
import cats.Show

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

What changed and how should we use imports from now on?

In 2.1.x instances of type classes were defined in separate objects so in order to be in scope (local scope) they had to be imported

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]
}

In 2.2.0 instances of type classes are defined in companion objects so they are in scope (implicit scope) automatically and do not have to be imported

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

Release notes 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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