【问题标题】:What does the Aux pattern accomplish in Scala?Aux 模式在 Scala 中完成了什么?
【发布时间】:2016-11-27 05:34:50
【问题描述】:

我对 Aux 模式(用于无形和其他地方)有一点了解,其中类型成员被提取到类型参数中,我知道这是一种解决方法,即同一参数列表中的参数可以'不依赖于彼此-但我一般不清楚它的用途以及它解决的问题。

例如,我目前正在尝试弄清楚如何保存和使用白盒宏返回的更具体的类型——这是 Aux 的用例吗?

有简单的说明吗?

【问题讨论】:

  • 查看我的回答here 进行一些讨论。

标签: scala typeclass shapeless scala-macros


【解决方案1】:

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

让我们看一下 shapeless 的 LabelledGeneric 类型类,它为您提供了一个通用的 HList 表示案例类:

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。我们可以有一个具体类型或一个类型变量。

这就是 Aux 发挥作用的地方:它让我们“提升”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 证明 Repr 是带有标签 T 的泛型表示,而 Keys.Aux 证明 K 是 Repr 的所有键的列表”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多