Aux 模式在 Scala 中完成了什么?
What does the Aux pattern accomplish in Scala?
我对 Aux 模式(在 shapeless 和其他地方使用的)有一些了解,在这种模式中,类型成员被提取到类型参数中,我知道这是一个解决方法,因为同一参数中的参数list 不能相互依赖 - 但我一般不清楚它的用途以及它解决的问题。
例如,我目前正在尝试弄清楚如何保留和使用白盒宏返回的更具体的类型——这是 Aux 的用例吗?
有简单的描述吗?
简单地说,此模式可让您在两个泛型类型参数之间建立关系。
让我们看一下 shapeless' LabelledGeneric
类型 class,它为您提供了一个通用的 HList
表示形式 classes:
trait LabelledGeneric[T] {
type Repr
}
T
是输入类型,即 LabelledGeneric[MyCaseClass]
将为您提供 MyCaseClass
的 HList 表示。 Repr
为输出类型,即T
.
对应的HList类型
让我们编写一个采用 Generic
实例并需要输出类型的另一个参数的方法。例如,我们可以使用 Keys
来收集标记为 generic
的字段名称
def fieldNames[T](implicit gen: LabelledGeneric[T], keys: Keys[gen.Repr]): keys.Repr …
除了这不起作用,因为 Scala 不允许您在此处访问 gen
或 keys
。我们可以有具体类型或类型变量。
这就是 Aux 发挥作用的地方:它让我们 "lift" 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,您可以将 Aux 理解为证明两个类型变量之间关系的谓词。在上面的示例中,您可以将其读作 "LabelledGeneric proves that Repr
is the generic representation with labels of T, and Keys.Aux proves that K is a list of all keys of Repr".
我对 Aux 模式(在 shapeless 和其他地方使用的)有一些了解,在这种模式中,类型成员被提取到类型参数中,我知道这是一个解决方法,因为同一参数中的参数list 不能相互依赖 - 但我一般不清楚它的用途以及它解决的问题。
例如,我目前正在尝试弄清楚如何保留和使用白盒宏返回的更具体的类型——这是 Aux 的用例吗?
有简单的描述吗?
简单地说,此模式可让您在两个泛型类型参数之间建立关系。
让我们看一下 shapeless' LabelledGeneric
类型 class,它为您提供了一个通用的 HList
表示形式 classes:
trait LabelledGeneric[T] {
type Repr
}
T
是输入类型,即 LabelledGeneric[MyCaseClass]
将为您提供 MyCaseClass
的 HList 表示。 Repr
为输出类型,即T
.
让我们编写一个采用 Generic
实例并需要输出类型的另一个参数的方法。例如,我们可以使用 Keys
来收集标记为 generic
def fieldNames[T](implicit gen: LabelledGeneric[T], keys: Keys[gen.Repr]): keys.Repr …
除了这不起作用,因为 Scala 不允许您在此处访问 gen
或 keys
。我们可以有具体类型或类型变量。
这就是 Aux 发挥作用的地方:它让我们 "lift" 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,您可以将 Aux 理解为证明两个类型变量之间关系的谓词。在上面的示例中,您可以将其读作 "LabelledGeneric proves that Repr
is the generic representation with labels of T, and Keys.Aux proves that K is a list of all keys of Repr".