我对Aux模式有一些了解(用于无形和其他地方),其中一个类型成员被提取到一个类型参数中,并且我知道这是一个解决方法,即同一个参数列表中的参数可以' t取决于对方 - 但我不清楚它的用途和解决的问题。Aux模式在Scala中完成了什么?
例如,我目前正试图弄清楚如何保留和处理由白盒宏返回的更具体的类型 - 这是Aux的用例吗?
有简单的描述吗?
我对Aux模式有一些了解(用于无形和其他地方),其中一个类型成员被提取到一个类型参数中,并且我知道这是一个解决方法,即同一个参数列表中的参数可以' t取决于对方 - 但我不清楚它的用途和解决的问题。Aux模式在Scala中完成了什么?
例如,我目前正试图弄清楚如何保留和处理由白盒宏返回的更具体的类型 - 这是Aux的用例吗?
有简单的描述吗?
简单地说,这种模式可以让你建立两个泛型类型参数之间的关系。
让我们来看看无形的LabelledGeneric
型类,它为您提供了一个通用的HList
表示为case类:
trait LabelledGeneric[T] {
type Repr
}
T
是输入型的,即LabelledGeneric[MyCaseClass]
会给你的MyCaseClass
的HList表示。 Repr
是输出类型,即对应于T
的HList类型。
我们来编写一个方法,它需要一个Generic
实例并需要输出类型的另一个参数。例如,我们可以使用Keys
收集的标记通用
def fieldNames[T](implicit gen: LabelledGeneric[T], keys: Keys[gen.Repr]): keys.Repr …
的字段名称除了这不起作用,因为Scala不会让你访问gen
或keys
这里。我们可以有一个具体的类型或类型变量。
这正是奥克斯发挥作用:它让我们的“升降机” gen.Repr
成类型变量:
object Generic {
type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 }
}
正如你可以看到Aux
类型给我们提供了一种从Repr
到一个类型的变量,所以我们终于可以定义foo
:
def foo[T, Repr, K](
implicit gen: LabelledGeneric.Aux[T, Repr],
keys: Keys.Aux[Repr, K]
): K …
如果你熟悉的Prolog您可以阅读奥克斯作为证明谓语两个类型变量之间的关系。在上面的例子中,你可以读为“LabelledGeneric证明Repr
是T的标签的通用表示,并且Keys.Aux证明K是Repr的所有键的列表”。
请参阅我的回答[here](http://stackoverflow.com/a/34548518/334519)进行一些讨论。 –