2016-07-23 16 views
5

我对Aux模式有一些了解(用于无​​形和其他地方),其中一个类型成员被提取到一个类型参数中,并且我知道这是一个解决方法,即同一个参数列表中的参数可以' t取决于对方 - 但我不清楚它的用途和解决的问题。Aux模式在Scala中完成了什么?

例如,我目前正试图弄清楚如何保留和处理由白盒宏返回的更具体的类型 - 这是Aux的用例吗?

有简单的描述吗?

+0

请参阅我的回答[here](http://stackoverflow.com/a/34548518/334519)进行一些讨论。 –

回答

5

简单地说,这种模式可以让你建立两个泛型类型参数之间的关系。

让我们来看看无形的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不会让你访问genkeys这里。我们可以有一个具体的类型或类型变量。

这正是奥克斯发挥作用:它让我们的“升降机” 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的所有键的列表”。

相关问题