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:
import scalaz._, Scalaz._
trait Gender
case object Male extends Gender
case object Female extends Gender
implicit val GenderShows: Show[Gender] = Show.shows {
case Male => "Male"
case Female => "Female"
}
def f[A: Show](x: A): String = implicitly[Show[A]].shows(x)
And then:
scala> val male: Gender = Male
male: Gender = Male
scala> f(male)
res0: String = Male
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).
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.