Macro to turn multiple implicits of type M[T1 <: T] into single M[T] when T is sealed.
Requirement is, that all methods of M[T] need to have exactly one discriminator parameter of type T.
trait M[T] {
 def do(t: T): String
 def doI(i: Int, t: T):String
 def doS(s: String)(t: T):String
} Macro would generate for you pattern matches using type of that discriminator parameter, and delegate execution to one of available in scope implicits M[T1 <: T].
sealed trait Product {
  def name: String
  def unitPrice: BigDecimal
}
case class Phone(name: String, unitPrice: BigDecimal) extends Product
case class Accessory(name: String, unitPrice: BigDecimal) extends Product
trait Pricer[T] {
  def calculatePrice(t: T, quantity: Int): BigDecimal
}
object StandardPrices {
  implicit val phonePricer = new Pricer[Phone] {
    def calculatePrice(p: Phone, quantity: Int): BigDecimal = p.unitPrice * quantity
  }
  implicit val accessoryPricer = new Pricer[Accessory] {
    def calculatePrice(p: Accessory, quantity: Int): BigDecimal = p.unitPrice * quantity
  }
}
object SecondAccessoryFor1Cent {
  implicit val accessoryPricer = new Pricer[Accessory] {
    def calculatePrice(p: Accessory, quantity: Int): BigDecimal = {
      val normalPriced = Math.ceil(quantity / 2.0).toInt
      val for1centPriced = quantity - normalPriced
      p.unitPrice * normalPriced + BigDecimal(0.01) * for1centPriced
    }
  }
}
object Main extends App {
  val standardPricer: Pricer[Product] = {
    import explicitImplicits._
    import StandardPrices.phonePricer
    import StandardPrices.accessoryPricer
    deriveFromImplicits[Product, Pricer]
  }
  val promotionalPricer: Pricer[Product] = {
    import explicitImplicits._
    import StandardPrices.phonePricer
    import SecondAccessoryFor1Cent.accessoryPricer
    deriveFromImplicits[Product, Pricer]
  }
  val shoppingCart: Map[Product, Int] = Map(
    Phone("Nexus 5", 100.0) -> 1,
    Accessory("Qi charger", 30) -> 3
  )
  val standardCartValues = shoppingCart.map(standardPricer.calculatePrice _ tupled)
  // standardCartValues: collection.immutable.Iterable[BigDecimal] = List(100.0, 90)
  val promotionalCartValues = shoppingCart.map(promotionalPricer.calculatePrice _ tupled)
  // promotionalCartValues: collection.immutable.Iterable[BigDecimal] = List(100.0, 60.01)
}resolvers += Resolver.bintrayRepo("lustefaniak", "maven")
libraryDependencies += "com.lustefaniak.explicitimplicits" %% "explicit-implicits" % "0.1.1"Or use demo project