我试图过滤掉可能位于层次结构中的案例类中的特定字段:
import shapeless._
object removeField {
import labelled._
import ops.record._
trait RemoveField[T] {
def removeField(t: T, field:Witness): HList
}
object RemoveField {
implicit def generic[F, G](implicit gen: LabelledGeneric.Aux[F, G], sg: Lazy[RemoveField[G]]): RemoveField[F] =
new RemoveField[F] {
def removeField(f: F, field:Witness) = sg.value.removeField(gen.to(f), field)
}
implicit def product: RemoveField[HNil] =
new RemoveField[HNil] {
def removeField(p: HNil, field:Witness): HList = HNil
}
implicit def product[K <: Symbol, V, T <: HList]
(implicit
key: Witness.Aux[K],
selector: Selector.Aux[FieldType[K, V] :: T, K, Symbol],
sv: Lazy[RemoveField[V]],
st: Lazy[RemoveField[T]]
): RemoveField[FieldType[K, V] :: T] =
new RemoveField[FieldType[K, V] :: T] {
def removeField(p: FieldType[K, V] :: T, field:Witness): HList = {
if (selector(p) == selector(p)) sv.value.removeField(p.head, field)
else p.head :: st.value.removeField(p.tail, field)
}
}
implicit def cnil: RemoveField[CNil] =
new RemoveField[CNil] {
def removeField(p: CNil, field:Witness) = HNil
}
implicit def coproduct[K <: Symbol, V, T <: Coproduct]
(implicit
key: Witness.Aux[K],
sv: Lazy[RemoveField[V]],
st: Lazy[RemoveField[T]]
): RemoveField[FieldType[K, V] :+: T] =
new RemoveField[FieldType[K, V] :+: T] {
def removeField(c: FieldType[K, V] :+: T, field:Witness): HList =
c match {
case Inl( head ) => sv.value.removeField(head, field )
case Inr( tail ) => st.value.removeField(tail, field )
}
}
}
implicit class RemoveFieldOps[T](x: T)(implicit removeFieldT: RemoveField[T]) {
def removeField(field:Witness): HList = removeFieldT.removeField(x, field)
}
sealed trait Animal
case class Cat(name: String, fish: Int) extends Animal
case class Dog(name: String, bones: Int) extends Animal
val felix:Cat = Cat("Felix", 1)
val tigger = Dog("Tigger", 2)
}
所以当我这样做时:
scala> import removeField._
import removeField._
scala> felix
res0: removeField.Cat = Cat(Felix,1)
scala> felix.removeField('name)
它没有编译,我认为问题是RemoveField[G]
无法找到,下面是隐式解决方案的完整痕迹,但我认为这应该是有效的
<console>:15: removeField.this.RemoveField.<product: error> is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]] because:
type mismatch;
found : [K <: Symbol, V, T <: shapeless.HList](implicit key: shapeless.Witness.Aux[K], implicit selector: shapeless.ops.record.Selector.Aux[shapeless.::[shapeless.labelled.FieldType[K,V],T],K,Symbol], implicit sv: shapeless.Lazy[removeField.RemoveField[V]], implicit st: shapeless.Lazy[removeField.RemoveField[T]])removeField.RemoveField[shapeless.::[shapeless.labelled.FieldType[K,V],T]] <and> => removeField.RemoveField[sh...<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
felix.removeField('name)
^
因为我理解LabelledGeneric
会&#34;返回&#34; V with KeyTag[K, V] :: T
又称FieldType[K, V]
类型的东西
其中K <: Symbol
和T <: HList
似乎这样做,类型是
Generic.Aux[
String with KeyTag[Symbol with Tagged[String("name"),String]] ::
Int with KeyTag[Symbol with Tagged[String("fish")],Int] ::
shapeless.HNil],
V
]
那么为什么我的类型类的product
实例&#34;选择&#34;那个?
完整的痕迹:
<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[removeField.Cat,V] because:
type parameters weren't correctly instantiated outside of the implicit tree: inferred type arguments [shapeless.::[String,shapeless.::[Int,shapeless.HNil]],Nothing] do not conform to method materializeCoproduct's type parameter bounds [V <: shapeless.Coproduct,R <: shapeless.Coproduct]
felix.removeField('name)
^
<console>:15: shapeless.this.LabelledGeneric.materializeCoproduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[removeField.Cat,G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[removeField.Cat,V]
felix.removeField('name)
^
<console>:15: removeField.this.RemoveField.<product: error> is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]] because:
type mismatch;
found : [K <: Symbol, V, T <: shapeless.HList](implicit key: shapeless.Witness.Aux[K], implicit selector: shapeless.ops.record.Selector.Aux[shapeless.::[shapeless.labelled.FieldType[K,V],T],K,Symbol], implicit sv: shapeless.Lazy[removeField.RemoveField[V]], implicit st: shapeless.Lazy[removeField.RemoveField[T]])removeField.RemoveField[shapeless.::[shapeless.labelled.FieldType[K,V],T]] <and> => removeField.RemoveField[sh...<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
felix.removeField('name)
^
<console>:15: shapeless.this.LabelledGeneric.materializeCoproduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V]
felix.removeField('name)
^
<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
felix.removeField('name)
^
<console>:15: shapeless.this.LabelledGeneric.materializeProduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V]
felix.removeField('name)
^
<console>:15: removeField.this.RemoveField.generic is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],G]
felix.removeField('name)
^
<console>:15: shapeless.this.Lazy.mkLazy is not a valid implicit value for shapeless.Lazy[removeField.RemoveField[this.Out]] because:
hasMatchingSymbol reported error: Unable to derive removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]]
felix.removeField('name)
^
<console>:15: removeField.this.RemoveField.generic is not a valid implicit value for removeField.RemoveField[removeField.Cat] because:
hasMatchingSymbol reported error: could not find Lazy implicit value of type removeField.RemoveField[G]
felix.removeField('name)
^
<console>:15: RemoveFieldOps is not a valid implicit value for removeField.felix.type => ?{def removeField: ?} because:
could not find implicit value for parameter removeFieldT: removeField.RemoveField[removeField.Cat]
felix.removeField('name)
^
<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[removeField.Cat,V] because:
type parameters weren't correctly instantiated outside of the implicit tree: inferred type arguments [shapeless.::[String,shapeless.::[Int,shapeless.HNil]],Nothing] do not conform to method materializeCoproduct's type parameter bounds [V <: shapeless.Coproduct,R <: shapeless.Coproduct]
felix.removeField('name)
^
<console>:15: shapeless.this.LabelledGeneric.materializeCoproduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[removeField.Cat,G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[removeField.Cat,V]
felix.removeField('name)
^
<console>:15: removeField.this.RemoveField.<product: error> is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]] because:
type mismatch;
found : [K <: Symbol, V, T <: shapeless.HList](implicit key: shapeless.Witness.Aux[K], implicit selector: shapeless.ops.record.Selector.Aux[shapeless.::[shapeless.labelled.FieldType[K,V],T],K,Symbol], implicit sv: shapeless.Lazy[removeField.RemoveField[V]], implicit st: shapeless.Lazy[removeField.RemoveField[T]])removeField.RemoveField[shapeless.::[shapeless.labelled.FieldType[K,V],T]] <and> => removeField.RemoveField[sh...<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
felix.removeField('name)
^
<console>:15: shapeless.this.LabelledGeneric.materializeCoproduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V]
felix.removeField('name)
^
<console>:15: shapeless.this.Generic.materialize is not a valid implicit value for shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V] because:
hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct
felix.removeField('name)
^
<console>:15: shapeless.this.LabelledGeneric.materializeProduct is not a valid implicit value for shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],G] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.Generic.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],V]
felix.removeField('name)
^
<console>:15: removeField.this.RemoveField.generic is not a valid implicit value for removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]] because:
hasMatchingSymbol reported error: could not find implicit value for parameter gen: shapeless.LabelledGeneric.Aux[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]],G]
felix.removeField('name)
^
<console>:15: shapeless.this.Lazy.mkLazy is not a valid implicit value for shapeless.Lazy[removeField.RemoveField[this.Out]] because:
hasMatchingSymbol reported error: Unable to derive removeField.RemoveField[shapeless.::[String with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("name")],String],shapeless.::[Int with shapeless.labelled.KeyTag[Symbol with shapeless.tag.Tagged[String("fish")],Int],shapeless.HNil]]]
felix.removeField('name)
^
<console>:15: removeField.this.RemoveField.generic is not a valid implicit value for removeField.RemoveField[removeField.Cat] because:
hasMatchingSymbol reported error: could not find Lazy implicit value of type removeField.RemoveField[G]
felix.removeField('name)
^
<console>:15: removeField.RemoveFieldOps is not a valid implicit value for removeField.felix.type => ?{def removeField: ?} because:
could not find implicit value for parameter removeFieldT: removeField.RemoveField[removeField.Cat]
felix.removeField('name)
^
<console>:15: error: value removeField is not a member of removeField.Cat
felix.removeField('name)
^