Получение экземпляра класса типа через родительский тип - PullRequest
0 голосов
/ 10 апреля 2020

Мне нужно предоставить экземпляры классов типов для группы классов, все они получены из одной черты, но, насколько я понимаю, Scala компилятор ожидает экземпляр для указанного c класса и не go вверх по иерархии наследования. Поэтому этот код:

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)
}

не компилируется с ошибкой чтения could not find implicit value for parameter ev: Printable[Impl]. Есть ли способ определить экземпляр класса одного типа для базовой черты и избежать повторения, возможно, используя Shapeless или что-то еще.

Ответы [ 2 ]

3 голосов
/ 10 апреля 2020

Полагаю, вы имеете в виду Printable[Concrete] (то есть Show экземпляр класса типов).

Необходимо обновить до printableBase определения, указанного ниже:

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)
}
2 голосов
/ 10 апреля 2020

Printable можно сделать контравариантным, добавив знак -:

trait Printable[-A]

Это делает Printable[X] подтипом Printable[Y], если Y является подтипом X. В частности, Printable[Base] является подтипом Printable[Concrete] и может использоваться, когда компилятор ищет неявный тип этого типа.

...