The usual trick is to write something like this:
trait LowPriorityAAInstances {
implicit def forgetAB[T: AB]: AA[T] = implicitly[AA[T]]
}
object AA extends LowPriorityAAInstances {
implicit def forgetBA[T: BA]: AA[T] = implicitly[AA[T]]
}
This will give forgetBA
priority when looking for an instance of AA
for a T
for which there's an instance of BA
(while still compiling even if there's an instance of AB
around).
The naming is entirely a matter of convention, but it's a good idea to use it to indicate that you're only breaking up the definition of AA
in this way to accommodate the implicit search mechanism.