scala - Aux 模式在 Scala 中完成了什么?

标签 scala typeclass shapeless scala-macros

我对 Aux 模式(在 shapeless 和其他地方使用)有一些了解,其中将类型成员提取到类型参数中,并且我知道这是一种解决方法,即同一参数列表中的参数不能依赖彼此 - 但我一般不清楚它的用途和解决什么问题。

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

有简单的说明吗?

最佳答案

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

让我们来看看无形的'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 type 为我们提供了一条来自 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 的所有键的列表”。

关于scala - Aux 模式在 Scala 中完成了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38541271/

相关文章:

scala - 按类型选择字段

scala - 如何使用 Shapeless 创建一个对 arity 进行抽象的函数

java - 如何修复 Kafka Producer 示例的 NoClassDefFoundError?

java - 解析嵌套 avro 文件

haskell - 在 Haskell 中,是否可以为部分应用的多参数类型类提供默认实现?

haskell - 是否存在使用代数数据类型或多态性的 OOP 抽象类的 Haskell 等效项?

scala - 如何将两个元组与兼容的类型结合起来?

mongodb - 使用 cashbah 在 Scala 中更新 Mongo 文档

scala - Scala 3 中是否仍然存在 volatile 类型?

scala - Scala 中带有两个参数的类型构造函数的仿函数实例