What does the Aux pattern accomplish in Scala?

江枫思渺然 提交于 2019-12-01 17:12:51

问题


I have a bit of a sense of the Aux pattern (as used in shapeless and elsewhere) in which a type member is extracted into a type parameter, and I know it's a workaround the fact that arguments in the same argument list can't depend on each other -- but I'm not clear generally what it's used for and what problems it solves.

For example, I'm currently trying to figure out how to preserve and work with the more specific type returned by a whitebox macro -- is this a usecase for Aux?

Is there a simple description?


回答1:


Simply speaking this pattern lets you establish a relation between two generic type parameters.

Let's take a look at shapeless' LabelledGeneric type class which gives you a generic HList representation for case classes:

trait LabelledGeneric[T] {
  type Repr
}

T is the input type, i.e LabelledGeneric[MyCaseClass] will give you the HList representation of MyCaseClass. Repr is the output type, i.e. the HList type corresponding to T.

Let's write a method that takes a Generic instance and needs another parameter of the output type. For instance we could use Keys to collect the field names of a labelled generic

def fieldNames[T](implicit gen: LabelledGeneric[T], keys: Keys[gen.Repr]): keys.Repr …

Except that this doesn't work because Scala doesn't let you access gen or keys here. We can either have a concrete type or a type variable.

And that's where Aux comes into play: It let's us "lift" gen.Repr into a type variable:

object Generic {
    type Aux[T, Repr0] = Generic[T] { type Repr = Repr0 }
}

As you can see the Aux type gives us a way from Repr to a type variable, so we can finally define foo:

def foo[T, Repr, K](
  implicit gen: LabelledGeneric.Aux[T, Repr],
  keys: Keys.Aux[Repr, K]
): K …

If you are familiar with Prolog you can read Aux as a predicate that proves a relation between two type variables. In the above example you can read it as "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".



来源:https://stackoverflow.com/questions/38541271/what-does-the-aux-pattern-accomplish-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!