I'm trying to make Gender
implement the Show
typeclass.
scala> trait Gender extends Show[Gender]
defined trait Gender
scala> case object Male extends Gender
defined object Male
scala> case object Female extends Gender
defined object Female
Next, I defined a function that calls show
on an implicit Show[A]
.
scala> def f[A : Show](x: A): String = implicitly[Show[A]].shows(x)
f: [A](x: A)(implicit evidence$1: scalaz.Show[A])String
Finally, I created an implicit class for Show[Gender]
:
scala> implicit class GenderShows(g: Gender) extends Show[Gender] {
| g match {
| case Male => "Male"
| case Female => "Female"
| }
| }
defined class GenderShows
I tried it out, but it's not finding such an implicit:
scala> val male: Gender = Male
male: Gender = Male
scala> f(male)
<console>:20: error: could not find implicit value for
evidence parameter of type scalaz.Show[Gender]
f(male)
^
This isn't really how type classes work. Instead of extending the type class in your class definition, you provide an instance for your type separately as an implicit value:
And then:
This is one of the big advantages of type classes over subtyping—they decouple the definition of your data types from the definition of the operations you want to support on those types (nobody wants to have to change their inheritance hierarchy every time they need to support a new serialization library, for example).