Scala 按类型选择字段

Scala 按类型选择字段,scala,shapeless,scala-implicits,Scala,Shapeless,Scala Implicits,我试图创建一个类型类,允许为给定类型选择字段。这是我到目前为止所做的,但编译器无法找到选择器.Aux case class AddressKey(street: String, city: String) trait AddressKeySelector[A] { def addressKey(v: A): AddressKey def addressKeyColumnName: String } object AddressKeySelector { implicit def

我试图创建一个类型类,允许为给定类型选择字段。这是我到目前为止所做的,但编译器无法找到选择器.Aux

case class AddressKey(street: String, city: String)

trait AddressKeySelector[A] {
  def addressKey(v: A): AddressKey
  def addressKeyColumnName: String
}

object AddressKeySelector {

  implicit def typeAddressKeySelector[A, Repr <: HList, K](
      implicit gen: Generic.Aux[A, Repr],
      reprSelector: Selector.Aux[Repr, K, AddressKey]): AddressKeySelector[A] =
    new AddressKeySelector[A] {
      override def addressKey(v: A): AddressKey = reprSelector(gen.to(v))

      override def addressKeyColumnName: String = ???
    }
}

只有当有一个且只有一个字段的类型为AddressKey时,这才有效。关于如何实现它有什么想法吗?

ops.hlist.Selector
没有
Aux
,所以我假设您正在使用它。鉴于要提取字段名,您可能需要使用
LabelledGeneric
ops.record.Selector
。但是
Selector.Aux[Repr,K,AddressKey]
仍然不起作用,因为
Selector
只能按“键”(
K
)搜索,而不能按“值”(
AddressKey
)搜索

理想情况下,我认为您可以这样实施:

import shapeless._, ops.record._

trait AddressKeySelector[A] {
  def addressKey(v: A): AddressKey
  def addressKeyColumnName: String
}

object AddressKeySelector {
  def apply[A](implicit sel: AddressKeySelector[A]): sel.type = sel

  implicit def typeAddressKeySelector[A, Repr <: HList, K <: Symbol, Swapped <: HList](
      implicit 
      gen: LabelledGeneric.Aux[A, Repr],
      swap: SwapRecord.Aux[Repr, Swapped],
      swappedSelector: Selector.Aux[Swapped, AddressKey, K],
      reprSelector: Selector.Aux[Repr, K, AddressKey]
  ): AddressKeySelector[A] =
    new AddressKeySelector[A] {
      override def addressKey(v: A): AddressKey = reprSelector(gen.to(v))

      override def addressKeyColumnName: String = swappedSelector(swap()).name
    }
}
import shapeless.\uu,ops.record_
特征地址键选择器[A]{
def地址键(v:A):地址键
def addressKeyColumnName:字符串
}
对象地址键选择器{
def apply[A](隐式sel:AddressKeySelector[A]):sel.type=sel

隐式def typeAddressKeySelector[A,Repr swapprecord类型类在做什么?它将
HList
中的每个
FieldType[K,V]
交换到
FieldType[V,K]
。您只能在键上选择。因此,如果您交换键和值,您可以在值(已成为键)上选择。按类型选择字段而不是使用符号似乎是一个合理的操作,我很惊讶没有一个类型类用于此,我也是。我认为它根本不需要,因为
swapercard
,但这似乎不起作用。。。
import shapeless._, ops.record._

trait AddressKeySelector[A] {
  def addressKey(v: A): AddressKey
  def addressKeyColumnName: String
}

object AddressKeySelector {
  def apply[A](implicit sel: AddressKeySelector[A]): sel.type = sel

  implicit def typeAddressKeySelector[A, Repr <: HList, K <: Symbol, Swapped <: HList](
      implicit 
      gen: LabelledGeneric.Aux[A, Repr],
      swap: SwapRecord.Aux[Repr, Swapped],
      swappedSelector: Selector.Aux[Swapped, AddressKey, K],
      reprSelector: Selector.Aux[Repr, K, AddressKey]
  ): AddressKeySelector[A] =
    new AddressKeySelector[A] {
      override def addressKey(v: A): AddressKey = reprSelector(gen.to(v))

      override def addressKeyColumnName: String = swappedSelector(swap()).name
    }
}