I suspect,
most are aware of the Show example to introduce type class.
I found out this blog post https://scalac.io/typeclasses-in-scala/, and was going trough it easy when i stumble upon something that i do not quite understand and was hopping that someone could help clarify it.
I understand everything in the blog post expect when it talks about implicit categories:
From the type class full definition with syntax and object interface
trait Show[A] {
def show(a: A): String
}
object Show {
def apply[A](implicit sh: Show[A]): Show[A] = sh
//needed only if we want to support notation: show(...)
def show[A: Show](a: A) = Show[A].show(a)
implicit class ShowOps[A: Show](a: A) {
def show = Show[A].show(a)
}
//type class instances
implicit val intCanShow: Show[Int] =
int => s"int $int"
implicit val stringCanShow: Show[String] =
str => s"string $str"
}
We get the following comment:
We may encounter a need to redefine some default type class instances. With the implementation above, if all default instances were imported into scope we cannot achieve that. The compiler will have ambiguous implicits in scope and will report an error.
We may decide to move the show function and the ShowOps implicit class to another object (let say ops) to allow users of this type class to redefine the default instance behaviour (with Category 1 implicits, more on categories of implicits). After such a modification, the Show object looks like this:
object Show {
def apply[A](implicit sh: Show[A]): Show[A] = sh
object ops {
def show[A: Show](a: A) = Show[A].show(a)
implicit class ShowOps[A: Show](a: A) {
def show = Show[A].show(a)
}
}
implicit val intCanShow: Show[Int] =
int => s"int $int"
implicit val stringCanShow: Show[String] =
str => s"string $str"
}
Usage does not change, but now the user of this type class may import only:
import show.Show
import show.Show.ops._
Default implicit instances are not brought as Category 1 implicits (although they are available as Category 2 implicits), so it’s possible to define our own implicit instance where we use such type class.
I don't get this last comment?