How can I hide my implicit method or disable "LabelledGeneric" for a specific sealed family?

I need to use third party traits that are designed as:

trait Super[T]
trait Sub[T] extends Super[T]


and I have defined the following method for providing instances for arbitrary sealed families:

implicit def subFor[T, Repr](
  gen: LabelledGeneric.Aux[T, Repr],
  sg: Lazy[JsonFormat[Repr]]
): Sub[T] = ???


but somewhere else in the code, someone has already defined

implicit def superFor[T]: Super[T] = ???


for some specific types, eg. Option

and several others.

In fact, I would like to use existing implementations instead of using my standard implementation subFor

. However, since my method returns Sub[T]

and returns an existing implementation, Super[T]

I see no way to define my implementation in such a way that it is considered a lower priority.

How can I block mine subFor

from being called for certain types? Is there a way to disable LabelledGeneric

for specific types, or some kind of priority reduction mechanism that the compiler from looking for mine subFor

if it already sees Super[T]



source to share

1 answer

If implicit defs are defined in companion objects, you must resort to collision-based type computation. But for "some concrete types" defs are usually not found in companion class objects (eg, not on object Option

). In this case, you can take advantage of the fact that the implications hide each other within a specific namespace. So you can simply

implicit def superFor[T]: SomeThrowawayType = ???


and they superFor

will no longer work. Since you are changing the return type, it won't collide or anything else; he actually just disappeared. Then you can create your own forwarders at whatever priority level you want to explicitly call their defs.

This requires, however, that you import your things after them (so they shadow them). If this seems too difficult to rely on, you have to look for type computations.



All Articles