Jos*_*cus 5 scala typeclass shapeless scala-macros
我有一点Aux模式的感觉(在无形和其他地方使用),其中一个类型成员被提取到一个类型参数,我知道这是一个解决方法,相同的参数列表中的参数不能依赖在彼此 - 但我一般不清楚它用于什么以及它解决了什么问题.
例如,我目前正在试图弄清楚如何保存和使用whitebox宏返回的更具体的类型 - 这是Aux的用例吗?
有简单的描述吗?
简单地说,此模式允许您在两个泛型类型参数之间建立关系.
让我们看看无形' LabelledGeneric类型类,它为您提供HList了案例类的通用表示:
trait LabelledGeneric[T] {
type Repr
}
Run Code Online (Sandbox Code Playgroud)
T是输入类型,LabelledGeneric[MyCaseClass]即将为您提供HList表示MyCaseClass. Repr是输出类型,即对应的HList类型T.
让我们编写一个接受Generic实例并需要输出类型的另一个参数的方法.例如,我们可以Keys用来收集标记泛型的字段名称
def fieldNames[T](implicit gen: LabelledGeneric[T], keys: Keys[gen.Repr]): keys.Repr …
Run Code Online (Sandbox Code Playgroud)
除非这不起作用,因为Scala不允许您访问gen或keys在此处.我们可以有一个具体类型或一个类型变量.
这就是Aux发挥作用的地方:它让我们"升级" gen.Repr为一个类型变量:
object Generic {
type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 }
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,Aux类型为我们提供了Repr一种类型变量,因此我们可以最终定义foo:
def foo[T, Repr, K](
implicit gen: LabelledGeneric.Aux[T, Repr],
keys: Keys.Aux[Repr, K]
): K …
Run Code Online (Sandbox Code Playgroud)
如果您熟悉Prolog,则可以将Aux作为谓词来读取,以证明两个类型变量之间的关系.在上面的示例中,您可以将其读作"LabelledGeneric证明这Repr是带有T标签的通用表示,而Keys.Aux证明K是Repr的所有键的列表".