scala – 过滤掉案例类中的字段
发布时间:2020-12-16 19:23:38 所属栏目:安全 来源:网络整理
导读:我正在尝试从可能位于层次结构中的案例类中过滤掉特定字段: import shapeless._object removeField { import labelled._ import ops.record._ trait RemoveField[T] { def removeField(t: T,field:Witness): HList } object RemoveField { implicit def gen
我正在尝试从可能位于层次结构中的案例类中过滤掉特定字段:
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,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,T <: Coproduct] (implicit key: Witness.Aux[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,T <: shapeless.HList](implicit key: shapeless.Witness.Aux[K],implicit selector: shapeless.ops.record.Selector.Aux[shapeless.::[shapeless.labelled.FieldType[K,V],T],implicit sv: shapeless.Lazy[removeField.RemoveField[V]],implicit st: shapeless.Lazy[removeField.RemoveField[T]])removeField.RemoveField[shapeless.::[shapeless.labelled.FieldType[K,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")],shapeless.HNil]],V] because: hasMatchingSymbol reported error: No Generic instance available for HList or Coproduct felix.removeField('name) ^ 因为据我所知,LabelledGeneric将使用KeyTag [K,V] :: T aka FieldType [K,V]“返回”V类型的东西 Generic.Aux[ String with KeyTag[Symbol with Tagged[String("name"),String]] :: Int with KeyTag[Symbol with Tagged[String("fish")],Int] :: shapeless.HNil],V ] 那么为什么我的类型类的产品实例不能“挑选”那个呢? <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,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")],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")],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")],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")],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")],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")],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")],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")],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,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) ^ 解决方法
事实证明这是不可能的,所以我最终写了这个而不是
https://github.com/caente/equals-except
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |