Search code examples
scalatypeclassimplicit

Getting type class instance through a parent type


I need to provide type class instances for a bunch of case classes all derived from a single trait, but as far as I understand Scala compiler expects an instance for a specific class and doesn't go up the inheritance hierarchy. So this code:

trait Base

sealed trait Child extends Base

case class Concrete() extends Child

trait Printable[A] {
  def print(value: A): String
}

object WtfTrait {
  def print[A](x: A)(implicit ev: Printable[A]) = {
    println(ev.print(x))
  }

  implicit val printableBase = new Printable[Base] {
    override def print(value: Base): String = value.toString
  }

  val x = Concrete()
  print(x)
}

doesn't compile with an error reading could not find implicit value for parameter ev: Printable[Impl]. Is there a way to define a single type class instance for the base trait and avoid repitition maybe by using Shapeless or something.


Solution

  • Guess you mean Printable[Concrete] (that's to say a Show typeclass instance).

    Need to update to printableBase definition as bellow:

    trait Base
    
    sealed trait Child extends Base
    
    case class Concrete() extends Child
    
    trait Printable[A] {
      def print(value: A): String
    }
    
    object WtfTrait {
      def print[A](x: A)(implicit ev: Printable[A]) = {
        println(ev.print(x))
      }
    
      // HERE
      implicit def printableBase[T <: Base] = new Printable[T] {
        override def print(value: T): String = value.toString
      }
    
      val x = Concrete()
      print(x)
    }