通过父类型获取类型 class 实例
Getting type class instance through a parent type
我需要为一堆案例 class 提供类型 class 实例,这些实例都是从单个特征派生的,但据我了解,Scala 编译器需要一个特定实例 class 并且不会上升到继承层次结构。所以这段代码:
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]
。有没有办法为基本特征定义单一类型 class 实例,并避免重复使用 Shapeless 或其他东西。
我猜你是说 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)
}
Printable
可以通过添加 -
符号来实现逆变:
trait Printable[-A]
这使得 Printable[X]
成为 Printable[Y]
的子类型,如果 Y
是 X
的子类型。特别是,Printable[Base]
是 Printable[Concrete]
的子类型,可以在编译器查找该类型的隐式时使用。
我需要为一堆案例 class 提供类型 class 实例,这些实例都是从单个特征派生的,但据我了解,Scala 编译器需要一个特定实例 class 并且不会上升到继承层次结构。所以这段代码:
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]
。有没有办法为基本特征定义单一类型 class 实例,并避免重复使用 Shapeless 或其他东西。
我猜你是说 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)
}
Printable
可以通过添加 -
符号来实现逆变:
trait Printable[-A]
这使得 Printable[X]
成为 Printable[Y]
的子类型,如果 Y
是 X
的子类型。特别是,Printable[Base]
是 Printable[Concrete]
的子类型,可以在编译器查找该类型的隐式时使用。