Two questions on type classes

  1. I would like to override equals to allow comparison of types within a type class. That doesn’t seem possible, though: equals deals with runtime types and type class evidences are summoned at compile-time. But maybe there’s a trick of some sort…

  2. The reason I ended up with type classes is that I’m mixing Scala and Java implementations, with slightly different signatures (e.g., Scala list vs Java list). I’m wondering where to put the given declarations that correspond to the Java implementations. It doesn’t look like I can have a Scala companion object to a Java class. Is there a standard practice?

  1. I could be wrong but I don’t think so. That is why all equality typeclasses out there simply define a new method like ===. BTW, can’t you use one of the existing ones? Like cats Eq?
  2. It could be in the companion object of the type class so you don’t need imports. Otherwise, any arbitrary object called either implicits or instances and then your users would need to import them.

Do you have an example of type class “out there” so I can see what they do with equality? (I stick to vanilla Scala in my teaching, so not cats for me. I’m more of a dog person anyway.)

I don’t think they belong to the companion object of the type class (conceptually) and I cannot have all of them there anyway without getting into ambiguities in the resolution of implicits. I can have the Scala ones in their respective companion objects (no imports needed) and deal with the Java ones using imports.

Versions of this exist in an enormous number of different libraries – cats aside, the same idea exists in everything from Slick to ScalaTest. It may well be the most commonly-copied typeclass out there, albeit with different nuances depending on the needs of the library.

It’s instructive to at least look at the Cats definition, which is (like most of Cats) highly generally and broadly useful, and it provides instances for a huge number of types alongside that.

1 Like

The first three define a new operator: === the last two reuse the traditional ==.
TBH, I have no idea how the fourth one can override ==, AFAIK extension methods are only searched if the type doesn’t have that method already implemented. Maybe == is always an extension? Not sure.

Anyways, note that one thing is overriding == and another is equals, you can always bypass any type safe equality. And stuff like Iterable.contains or Map.get will use the default equality regardless.

Which is why IMHO is better to use a different symbol like === to make it explicit.


Uhm why not?
The companion object of a typeclass is the natural place for default / common instances.

Uhm the priority trick may be used here, is hard to tell without seeing the code.

Anyways, yeah, there is nothing wrong with having them in a different object or objects, and manually importing them.
It is just usual for folks to want a more “out of the box” UX without needing imports.

1 Like

I’ve looked at === from Scalatest in the past but somehow didn’t make the connection with my current situation. I see what I need to do now.