如何在运行时获取适当的类型类实例?

时间:2017-03-18 22:19:00

标签: scala typeclass shapeless

第一部分

假设我有一个类型类trait Show[T] { def print(t: T): String },其中包含StringInt的实例。假设我有一个值,其特定类型仅在运行时知道:

val x: Any = ...

如何获取相应的类型类实例(在运行时,因为我们不能静态地知道类型)并使用它做一些事情。

请注意,定义一个字面上只给我们类型类实例的方法是不够的:

def instance(x: Any): Show[_]

由于Show.print需要静态已知的参数类型T,我们仍然无法对instance的结果执行任何操作。实际上,我们需要能够动态调度到使用实例的已定义函数,例如:

def display[T](t: T)(implicit show: Show[T]) = "show: " + show.print(t) + "\n"

因此,假设定义了display,我们如何调用display,传递适当的Show实例。即正确调用display(x)的东西。

Miles Sabin在这里使用运行时编译(Scala eval)完成了这个,作为" staging"的一个示例,但只有备用文档来说明发生了什么:

https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/staging.scala

Miles的方法可以放入图书馆吗?此外,这种方法的局限性是什么?关于像Seq[T]这样的泛型类型?

第二部分

现在假设T受到密封类型的限制(这样可以枚举所有子类型):

trait Show[T <: Foo]
sealed trait Foo
case class Alpha(..) extends Foo
case class Beta(..) extends Foo

在这种情况下,我们可以使用宏而不是运行时编译吗?并且可以在某些库中提供此功能吗?

我最关心的是Scala 2.12,但如果解决方案在2.11或2.10中有效,那么值得一提。

0 个答案:

没有答案