Scala 具有隐式解析的无形状pb的自定义类型类

Scala 具有隐式解析的无形状pb的自定义类型类,scala,shapeless,play-json,Scala,Shapeless,Play Json,我正在尝试使用shapeless从任意case类读取json 目前,我正在尝试实施以下步骤 从T开始,我有一个FieldType[K1,V1]::FieldType[K2,V2]:。。。使用标线 然后我想构建一个类型为Reads[V1]::Reads[V2]的HList 以下是我正在使用的代码: /* * To build the json reads from T */ trait HReads[PRepr <: HList] { type Out

我正在尝试使用shapeless从任意case类读取json

目前,我正在尝试实施以下步骤

从T开始,我有一个FieldType[K1,V1]::FieldType[K2,V2]:。。。使用标线

然后我想构建一个类型为Reads[V1]::Reads[V2]的HList

以下是我正在使用的代码:

  /*
   * To build the json reads from T 
   */
  trait HReads[PRepr <: HList] {
    type Out
    def reads: Out
  }

  object HReads {
    type Aux[PRepr <: HList, Out1 <: HList] = HReads[PRepr] { type Out = Out1 }

    implicit def readsHNil(): Aux[HNil, HNil] = new HReads[HNil] {
      type Out = HNil
      override def reads: Out = {
        throw new RuntimeException("Oups")
      }
    }

    implicit def readsSingleton[T, K <: Symbol](
       implicit
       kWitness: Witness.Aux[K],
       jsReads: play.api.libs.json.Reads[T]
     ): Aux[FieldType[K, T] :: HNil, Reads[T] :: HNil] = new HReads[FieldType[K, T] :: HNil] {
      type Out = Reads[T] :: HNil
      override def reads: Out = {
        val name: String = kWitness.value.name
        val pathReads: Reads[T] = (__ \ name).read[T](jsReads)
        pathReads :: HNil
      }
    }

    implicit def readsStd[T, K <: Symbol, RestRepr <: HList, Rest <: HList](
     implicit
     kWitness: Witness.Aux[K],
     jsReads: Reads[T],
     hreads: Lazy[HReads.Aux[RestRepr, Rest]]
    ): Aux[FieldType[K, T] :: RestRepr, Reads[T] :: Rest] = new HReads[FieldType[K, T] :: RestRepr] {
      type Out = Reads[T] :: Rest
      override def reads: Out = {
        val name: String = kWitness.value.name
        val pathReads: Reads[T] = (__ \ name).read[T](jsReads)
        val value: Rest = hreads.value.reads
        pathReads :: value
      }
    }

    def jsonReads[P]: JsonReads[P] = new JsonReads[P] {}

    implicit class JsonReadsOps[In](in: JsonReads[In]) {
      def jsonReads[K <: Symbol, T, InRepr <: HList, HR <: HList]()(
          implicit
          gen: LabelledGeneric.Aux[In, FieldType[K, T] :: InRepr],
          hreads: HReads.Aux[FieldType[K, T] :: InRepr, Reads[T] :: HR]
      ): Reads[T] :: HR = {
        hreads.reads
      }
    }
  }

  // And trying to use this like that : 
    import HReads._

  implicit val l = LabelledGeneric[MonPojo]

  private val allReads = jsonReads[MonPojo].jsonReads()
  println(s"All Reads $allReads")
  //[error] validation\validation.scala:428: could not find implicit value for parameter hreads: validation.validations.HReads.Aux[shapeless.labelled.FieldType[K,T] :: InRepr,play.api.libs.json.Reads[T] :: HR]
  //[error]   private val allReads = jsonReads[MonPojo].jsonReads()
  //[error]                                                      ^
  //[error] one error found
/*
*要构建json,请从
*/
特征线程
然后我想构建一个类型为Reads[V1]::Reads[V2]的HList

不清楚为什么需要读取的HList而不是读取的HList(因此我想您不需要其他类型的类HReads,读取就足够了)。我想您需要实现隐式:

implicit val readsHNil: Reads[HNil] = ???

implicit def readHCons[K <: Symbol, H, T <: HList](implicit
                                                     witness: Witness.Aux[K],
                                                     readsH: Reads[H],
                                                     readsT: Reads[T]): Reads[FieldType[K, H] :: T] = ???

implicit def readsGeneric[Repr, A](implicit
                                     gen: LabelledGeneric.Aux[A, Repr],
                                     readsRepr: Lazy[Reads[Repr]]): Reads[A] = ???
答案部分基于图书馆

然后我想构建一个类型为Reads[V1]::Reads[V2]的HList

不清楚为什么需要读取的HList而不是读取的HList(因此我想您不需要其他类型的类HReads,读取就足够了)。我想您需要实现隐式:

implicit val readsHNil: Reads[HNil] = ???

implicit def readHCons[K <: Symbol, H, T <: HList](implicit
                                                     witness: Witness.Aux[K],
                                                     readsH: Reads[H],
                                                     readsT: Reads[T]): Reads[FieldType[K, H] :: T] = ???

implicit def readsGeneric[Repr, A](implicit
                                     gen: LabelledGeneric.Aux[A, Repr],
                                     readsRepr: Lazy[Reads[Repr]]): Reads[A] = ???

答案部分基于库。

我可以让您的代码像这样工作

implicit def readHCons[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                               witness: Witness.Aux[K],
                                                               readsH: Reads[H],
                                                               readsT: Reads[T]): Reads[FieldType[K, H] :: T] =
  new Reads[FieldType[K, H] :: T] {
      override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
        val name = witness.value
        val jsonH = (__ \ name).read(readsH).reads(json)
        val jsonT = readsT.reads(json)
        (jsonH and jsonT) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T])
      }
    }
我试着用这个修改你的代码

  trait ReadsWithRules[T, R <: HList] {
    def withRules(rules: R): Reads[T]
  }

  trait ReadsWithRulesLowerPriority {

    implicit def readsHNil[R <: HNil]: ReadsWithRules[HNil, R] = new ReadsWithRules[HNil, R] {
      def withRules(rules: R) =
        new Reads[HNil] {
          override def reads(json: JsValue): JsResult[HNil] = JsSuccess(HNil)
        }
    }

    implicit def readHCons[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                   witness: Witness.Aux[K],
                                                                   readsH: Reads[H],
                                                                   readsT: ReadsWithRules[T, R]): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R) = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val jsonH = (__ \ name).read(readsH)
            val jsonT = readsT.withRules(rules)
            (jsonH and jsonT) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

  }

  object ReadsWithRules extends ReadsWithRulesLowerPriority {


    implicit def readHConsWithRule[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                   witness: Witness.Aux[K],
                                                                   at: shapeless.ops.record.Selector.Aux[R, K, Reads[H]],
                                                                   w: <:<[H, JsValue],
                                                                   readsH: Reads[H],
                                                                   readsT: ReadsWithRules[T, R]): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R) = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val additionnalRule: Reads[H] = at(rules)
            val jsonH = (__ \ name).read(readsH).andThen(additionnalRule)
            val jsonT = readsT
            (jsonH and jsonT.withRules(rules)) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

    implicit def readsGeneric[Repr, A, R <: HList](implicit
                                                   gen: LabelledGeneric.Aux[A, Repr],
                                                   readsRepr: Lazy[ReadsWithRules[Repr, R]]): ReadsWithRules[A, R] =
      new ReadsWithRules[A, R] {
        override def withRules(rules: R) : Reads[A] = {
          readsRepr.value.withRules(rules).map(r => gen.from(r))
        }
      }

    implicit class WithRules[T](gen: LabelledGeneric[T]) {
      def readsWithRules[R <: HList](rules: R)(implicit readWithRule: ReadsWithRules[T, R]): Reads[T] = {
        readWithRule.withRules(rules)
      }
    }
  }

trait readswithroles[T,R我可以让你的代码像这样工作

implicit def readHCons[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                               witness: Witness.Aux[K],
                                                               readsH: Reads[H],
                                                               readsT: Reads[T]): Reads[FieldType[K, H] :: T] =
  new Reads[FieldType[K, H] :: T] {
      override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
        val name = witness.value
        val jsonH = (__ \ name).read(readsH).reads(json)
        val jsonT = readsT.reads(json)
        (jsonH and jsonT) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T])
      }
    }
我试着用这个修改你的代码

  trait ReadsWithRules[T, R <: HList] {
    def withRules(rules: R): Reads[T]
  }

  trait ReadsWithRulesLowerPriority {

    implicit def readsHNil[R <: HNil]: ReadsWithRules[HNil, R] = new ReadsWithRules[HNil, R] {
      def withRules(rules: R) =
        new Reads[HNil] {
          override def reads(json: JsValue): JsResult[HNil] = JsSuccess(HNil)
        }
    }

    implicit def readHCons[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                   witness: Witness.Aux[K],
                                                                   readsH: Reads[H],
                                                                   readsT: ReadsWithRules[T, R]): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R) = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val jsonH = (__ \ name).read(readsH)
            val jsonT = readsT.withRules(rules)
            (jsonH and jsonT) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

  }

  object ReadsWithRules extends ReadsWithRulesLowerPriority {


    implicit def readHConsWithRule[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                   witness: Witness.Aux[K],
                                                                   at: shapeless.ops.record.Selector.Aux[R, K, Reads[H]],
                                                                   w: <:<[H, JsValue],
                                                                   readsH: Reads[H],
                                                                   readsT: ReadsWithRules[T, R]): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R) = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val additionnalRule: Reads[H] = at(rules)
            val jsonH = (__ \ name).read(readsH).andThen(additionnalRule)
            val jsonT = readsT
            (jsonH and jsonT.withRules(rules)) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

    implicit def readsGeneric[Repr, A, R <: HList](implicit
                                                   gen: LabelledGeneric.Aux[A, Repr],
                                                   readsRepr: Lazy[ReadsWithRules[Repr, R]]): ReadsWithRules[A, R] =
      new ReadsWithRules[A, R] {
        override def withRules(rules: R) : Reads[A] = {
          readsRepr.value.withRules(rules).map(r => gen.from(r))
        }
      }

    implicit class WithRules[T](gen: LabelledGeneric[T]) {
      def readsWithRules[R <: HList](rules: R)(implicit readWithRule: ReadsWithRules[T, R]): Reads[T] = {
        readWithRule.withRules(rules)
      }
    }
  }

trait readswithroles[T,R以下是readswithroles的实现:

  trait ReadsWithRules[T, R <: HList] {
    def withRules(rules: R): Reads[T]
  }

  trait ReadsWithRulesLowerPriority {
    implicit def readsNoRule[T](implicit reads: Reads[T]): ReadsWithRules[T, HNil] = new ReadsWithRules[T, HNil] {
      override def withRules(rules: HNil): Reads[T] = reads
    }

    implicit def readsGeneric[Repr, A, R <: HList](implicit
                                                   gen: LabelledGeneric.Aux[A, Repr],
                                                   readsRepr: Lazy[ReadsWithRules[Repr, R]]
                                                  ): ReadsWithRules[A, R] =
      new ReadsWithRules[A, R] {
        override def withRules(rules: R): Reads[A] = {
          readsRepr.value.withRules(rules).map(r => gen.from(r))
        }
      }

  }

  object ReadsWithRules extends ReadsWithRulesLowerPriority {
    implicit def readHNil[R <: HList]: ReadsWithRules[HNil, R] = new ReadsWithRules[HNil, R] {
      override def withRules(rules: R): Reads[HNil] = implicitly[Reads[HNil]]
    }

    implicit def readNoRuleForHead[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                           witness: Witness.Aux[K],
                                                                           noRule: LacksKey[R, K],
                                                                           readsH: Reads[H],
                                                                           readsT: ReadsWithRules[T, R]
                                                                          ): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R): Reads[FieldType[K, H] :: T] = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val rH = (__ \ name).read(readsH)
            (rH and readsT.withRules(rules)) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

    implicit def readRuleForHead[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                         witness: Witness.Aux[K],
                                                                         at: shapeless.ops.record.Selector.Aux[R, K, Reads[H]],
                                                                         readsH: Reads[H],
                                                                         readsT: ReadsWithRules[T, R]
                                                                        ): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R): Reads[FieldType[K, H] :: T] = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val additionalRule: Reads[H] = at(rules)
            val rH = (__ \ name).read(readsH) andKeep (__ \ name).read(additionalRule)
            (rH and readsT.withRules(rules)) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

  }

  def readsWithRules[T, R <: HList](rules: R)(implicit readWithRule: ReadsWithRules[T, R]): Reads[T] =
    readWithRule.withRules(rules)

  case class MonPojo(numericField: Int)

  val r: Reads[MonPojo] = 
      readsWithRules[MonPojo, FieldType[Symbol with Tagged["numericField"], Reads[Int]] :: HNil](
        ('numericField ->> (min(0) keepAnd max(150))) :: HNil
      )
  println(
    r.reads(Json.obj(
      "stringField" -> "Tata",
      "numericField" -> 42
    ))
  )

  //JsSuccess(MonPojo(42),)

trait readswithroles[T,R以下是readswithroles的实现:

  trait ReadsWithRules[T, R <: HList] {
    def withRules(rules: R): Reads[T]
  }

  trait ReadsWithRulesLowerPriority {
    implicit def readsNoRule[T](implicit reads: Reads[T]): ReadsWithRules[T, HNil] = new ReadsWithRules[T, HNil] {
      override def withRules(rules: HNil): Reads[T] = reads
    }

    implicit def readsGeneric[Repr, A, R <: HList](implicit
                                                   gen: LabelledGeneric.Aux[A, Repr],
                                                   readsRepr: Lazy[ReadsWithRules[Repr, R]]
                                                  ): ReadsWithRules[A, R] =
      new ReadsWithRules[A, R] {
        override def withRules(rules: R): Reads[A] = {
          readsRepr.value.withRules(rules).map(r => gen.from(r))
        }
      }

  }

  object ReadsWithRules extends ReadsWithRulesLowerPriority {
    implicit def readHNil[R <: HList]: ReadsWithRules[HNil, R] = new ReadsWithRules[HNil, R] {
      override def withRules(rules: R): Reads[HNil] = implicitly[Reads[HNil]]
    }

    implicit def readNoRuleForHead[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                           witness: Witness.Aux[K],
                                                                           noRule: LacksKey[R, K],
                                                                           readsH: Reads[H],
                                                                           readsT: ReadsWithRules[T, R]
                                                                          ): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R): Reads[FieldType[K, H] :: T] = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val rH = (__ \ name).read(readsH)
            (rH and readsT.withRules(rules)) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

    implicit def readRuleForHead[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                         witness: Witness.Aux[K],
                                                                         at: shapeless.ops.record.Selector.Aux[R, K, Reads[H]],
                                                                         readsH: Reads[H],
                                                                         readsT: ReadsWithRules[T, R]
                                                                        ): ReadsWithRules[FieldType[K, H] :: T, R] =
      new ReadsWithRules[FieldType[K, H] :: T, R] {
        override def withRules(rules: R): Reads[FieldType[K, H] :: T] = new Reads[FieldType[K, H] :: T] {
          override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
            val name = witness.value
            val additionalRule: Reads[H] = at(rules)
            val rH = (__ \ name).read(readsH) andKeep (__ \ name).read(additionalRule)
            (rH and readsT.withRules(rules)) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
          }
        }
      }

  }

  def readsWithRules[T, R <: HList](rules: R)(implicit readWithRule: ReadsWithRules[T, R]): Reads[T] =
    readWithRule.withRules(rules)

  case class MonPojo(numericField: Int)

  val r: Reads[MonPojo] = 
      readsWithRules[MonPojo, FieldType[Symbol with Tagged["numericField"], Reads[Int]] :: HNil](
        ('numericField ->> (min(0) keepAnd max(150))) :: HNil
      )
  println(
    r.reads(Json.obj(
      "stringField" -> "Tata",
      "numericField" -> 42
    ))
  )

  //JsSuccess(MonPojo(42),)

trait readswithroles[T,R我终于以另一种方式成功了:

object rules {

  import play.api.libs.json._
  import play.api.libs.functional.syntax._
  import scala.annotation.implicitNotFound
  import shapeless.labelled._
  import shapeless.syntax.singleton._
  import shapeless.{::, HList, HNil, LabelledGeneric, Lazy, Witness}
  import shapeless.ops.record.Selector

  trait SequenceReads[In <: HList] {
    type Out

    def apply(in: In): Reads[Out]
  }

  object SequenceReads {

    import play.api.libs.functional.syntax._

    type Aux[A <: HList, B <: HList] = SequenceReads[A] {type Out = B}

    implicit def sequenceHnil[T, R <: HList, TR <: HList](): Aux[HNil, HNil] = new SequenceReads[HNil] {
      type Out = HNil

      override def apply(in: HNil): Reads[Out] = {
        throw new RuntimeException("Oups")
      }
    }

    implicit def sequenceSingleton[T, K <: Symbol](
                                                    implicit witness: Witness.Aux[K]
                                                  ): Aux[FieldType[K, Reads[T]] :: HNil, T :: HNil] = new SequenceReads[FieldType[K, Reads[T]] :: HNil] {
      type Out = T :: HNil

      override def apply(in: FieldType[K, Reads[T]] :: HNil): Reads[T :: HNil] = {
        val name = witness.value.name
        (__ \ name).read(in.head).map(_ :: HNil)
      }
    }

    implicit def sequence[T, K <: Symbol, R <: HList, TR <: HList](
                                                                    implicit
                                                                    witness: Witness.Aux[K],
                                                                    req: Lazy[SequenceReads.Aux[R, TR]]
                                                                  ): Aux[FieldType[K, Reads[T]] :: R, T :: TR] = new SequenceReads[FieldType[K, Reads[T]] :: R] {

      type Out = T :: TR

      override def apply(in: FieldType[K, Reads[T]] :: R): Reads[Out] = {
        val name = witness.value.name
        val head: Reads[T] = (__ \ name).read(in.head)
        val value: Reads[TR] = req.value.apply(in.tail)
        (head and value) {
          _ :: _
        }
      }
    }

    implicit class SequenceReadsOps[In <: HList](in: In) {

      class Builder[Out <: HList] {
        def apply(
                   implicit
                   sequence: SequenceReads.Aux[In, Out]
                 ): Reads[Out] = {
          sequence(in)
        }
      }

      def sequence[R <: HList](implicit s: SequenceReads.Aux[In, R]) = new Builder[R].apply(s)
    }

  }

  @implicitNotFound("Implicit not found: Rules type or fields are not valid")
  trait RuleValidation[Repr <: HList, Rules <: HList]

  object RuleValidation {

    implicit def validateHNil[Repr <: HList] : RuleValidation[Repr, HNil] =
      new RuleValidation[Repr, HNil] {}

    implicit def validateSingleton[Repr <: HList, K <: Symbol, V] (
       implicit
       sel: Selector.Aux[Repr, K, V]
     ): RuleValidation[Repr, FieldType[K, Reads[V]] :: HNil] =
      new RuleValidation[Repr, FieldType[K, Reads[V]] :: HNil] {}

    implicit def validateHCons[Repr <: HList, H, R <: HList, K <: Symbol, V] (
      implicit
      sel: Selector.Aux[Repr, K, V],
      validation: RuleValidation[Repr, R]
    ): RuleValidation[Repr, FieldType[K, Reads[V]] :: R] =
      new RuleValidation[Repr, FieldType[K, Reads[V]] :: R] {}
  }

  object ReadsWithRules {



    implicit def readsHNil: Reads[HNil] = new Reads[HNil] {
      override def reads(json: JsValue): JsResult[HNil] = JsSuccess(HNil)
    }


    implicit def readHCons[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                   witness: Witness.Aux[K],
                                                                   readsH: Reads[H],
                                                                   readsT: Reads[T]): Reads[FieldType[K, H] :: T] =
      new Reads[FieldType[K, H] :: T] {
        override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
          val name = witness.value
          val jsonH = (__ \ name).read(readsH)
          val jsonT = readsT
          (jsonH and jsonT) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
        }
      }

    implicit def readsGeneric[Repr, A, R <: HList](implicit
                                                   gen: LabelledGeneric.Aux[A, Repr],
                                                   readsRepr: Lazy[Reads[Repr]]): Reads[A] = {
      readsRepr.value.map(r => gen.from(r))
    }
  }

  trait JsonRead[T]

  def jsonRead[T]: JsonRead[T] = new JsonRead[T] {}

  implicit class WithRules[A](gen: JsonRead[A]) {
    def readsWithRules[R <: HList, K <: Symbol, V, T0 <: HList, ARepr <: HList, AKeys <: HList, RKeys <: HList, Validation <: HList](rules: FieldType[K, V] :: T0)(
      implicit
      genA: LabelledGeneric.Aux[A, ARepr],
      readsInst: Reads[A],
      sequenceReads: SequenceReads[FieldType[K, V] :: T0],
      validation: RuleValidation[ARepr, FieldType[K, V] :: T0]
    ): Reads[A] = Reads[A] { json =>
      val valueA: JsResult[A] = readsInst.reads(json)
      val valueR: JsResult[sequenceReads.Out] = sequenceReads(rules).reads(json)
      (valueA, valueR) match {
        case (err1: JsError, err2: JsError) => err1 ++ err2
        case (err1: JsError, JsSuccess(_, _)) => err1
        case (JsSuccess(_, _), err2: JsError) => err2
        case (JsSuccess(v, p), _) => JsSuccess(v, p)
      }
    }
  }

}

感谢您的帮助,我将尝试您的解决方案。

我最终以另一种方式获得成功:

object rules {

  import play.api.libs.json._
  import play.api.libs.functional.syntax._
  import scala.annotation.implicitNotFound
  import shapeless.labelled._
  import shapeless.syntax.singleton._
  import shapeless.{::, HList, HNil, LabelledGeneric, Lazy, Witness}
  import shapeless.ops.record.Selector

  trait SequenceReads[In <: HList] {
    type Out

    def apply(in: In): Reads[Out]
  }

  object SequenceReads {

    import play.api.libs.functional.syntax._

    type Aux[A <: HList, B <: HList] = SequenceReads[A] {type Out = B}

    implicit def sequenceHnil[T, R <: HList, TR <: HList](): Aux[HNil, HNil] = new SequenceReads[HNil] {
      type Out = HNil

      override def apply(in: HNil): Reads[Out] = {
        throw new RuntimeException("Oups")
      }
    }

    implicit def sequenceSingleton[T, K <: Symbol](
                                                    implicit witness: Witness.Aux[K]
                                                  ): Aux[FieldType[K, Reads[T]] :: HNil, T :: HNil] = new SequenceReads[FieldType[K, Reads[T]] :: HNil] {
      type Out = T :: HNil

      override def apply(in: FieldType[K, Reads[T]] :: HNil): Reads[T :: HNil] = {
        val name = witness.value.name
        (__ \ name).read(in.head).map(_ :: HNil)
      }
    }

    implicit def sequence[T, K <: Symbol, R <: HList, TR <: HList](
                                                                    implicit
                                                                    witness: Witness.Aux[K],
                                                                    req: Lazy[SequenceReads.Aux[R, TR]]
                                                                  ): Aux[FieldType[K, Reads[T]] :: R, T :: TR] = new SequenceReads[FieldType[K, Reads[T]] :: R] {

      type Out = T :: TR

      override def apply(in: FieldType[K, Reads[T]] :: R): Reads[Out] = {
        val name = witness.value.name
        val head: Reads[T] = (__ \ name).read(in.head)
        val value: Reads[TR] = req.value.apply(in.tail)
        (head and value) {
          _ :: _
        }
      }
    }

    implicit class SequenceReadsOps[In <: HList](in: In) {

      class Builder[Out <: HList] {
        def apply(
                   implicit
                   sequence: SequenceReads.Aux[In, Out]
                 ): Reads[Out] = {
          sequence(in)
        }
      }

      def sequence[R <: HList](implicit s: SequenceReads.Aux[In, R]) = new Builder[R].apply(s)
    }

  }

  @implicitNotFound("Implicit not found: Rules type or fields are not valid")
  trait RuleValidation[Repr <: HList, Rules <: HList]

  object RuleValidation {

    implicit def validateHNil[Repr <: HList] : RuleValidation[Repr, HNil] =
      new RuleValidation[Repr, HNil] {}

    implicit def validateSingleton[Repr <: HList, K <: Symbol, V] (
       implicit
       sel: Selector.Aux[Repr, K, V]
     ): RuleValidation[Repr, FieldType[K, Reads[V]] :: HNil] =
      new RuleValidation[Repr, FieldType[K, Reads[V]] :: HNil] {}

    implicit def validateHCons[Repr <: HList, H, R <: HList, K <: Symbol, V] (
      implicit
      sel: Selector.Aux[Repr, K, V],
      validation: RuleValidation[Repr, R]
    ): RuleValidation[Repr, FieldType[K, Reads[V]] :: R] =
      new RuleValidation[Repr, FieldType[K, Reads[V]] :: R] {}
  }

  object ReadsWithRules {



    implicit def readsHNil: Reads[HNil] = new Reads[HNil] {
      override def reads(json: JsValue): JsResult[HNil] = JsSuccess(HNil)
    }


    implicit def readHCons[K <: Symbol, H, T <: HList, R <: HList](implicit
                                                                   witness: Witness.Aux[K],
                                                                   readsH: Reads[H],
                                                                   readsT: Reads[T]): Reads[FieldType[K, H] :: T] =
      new Reads[FieldType[K, H] :: T] {
        override def reads(json: JsValue): JsResult[FieldType[K, H] :: T] = {
          val name = witness.value
          val jsonH = (__ \ name).read(readsH)
          val jsonT = readsT
          (jsonH and jsonT) ((a, b) => (name ->> a :: b).asInstanceOf[FieldType[K, H] :: T]).reads(json)
        }
      }

    implicit def readsGeneric[Repr, A, R <: HList](implicit
                                                   gen: LabelledGeneric.Aux[A, Repr],
                                                   readsRepr: Lazy[Reads[Repr]]): Reads[A] = {
      readsRepr.value.map(r => gen.from(r))
    }
  }

  trait JsonRead[T]

  def jsonRead[T]: JsonRead[T] = new JsonRead[T] {}

  implicit class WithRules[A](gen: JsonRead[A]) {
    def readsWithRules[R <: HList, K <: Symbol, V, T0 <: HList, ARepr <: HList, AKeys <: HList, RKeys <: HList, Validation <: HList](rules: FieldType[K, V] :: T0)(
      implicit
      genA: LabelledGeneric.Aux[A, ARepr],
      readsInst: Reads[A],
      sequenceReads: SequenceReads[FieldType[K, V] :: T0],
      validation: RuleValidation[ARepr, FieldType[K, V] :: T0]
    ): Reads[A] = Reads[A] { json =>
      val valueA: JsResult[A] = readsInst.reads(json)
      val valueR: JsResult[sequenceReads.Out] = sequenceReads(rules).reads(json)
      (valueA, valueR) match {
        case (err1: JsError, err2: JsError) => err1 ++ err2
        case (err1: JsError, JsSuccess(_, _)) => err1
        case (JsSuccess(_, _), err2: JsError) => err2
        case (JsSuccess(v, p), _) => JsSuccess(v, p)
      }
    }
  }

}

感谢您的帮助,我将尝试您的解决方案。

我刚刚发布了一个答案,请参见上面的回复我刚刚发布了一个答案,请参见上面的回复亲爱的@Larousso,太好了,您终于通过排序实现了您的原始想法。不客气,很高兴与您交流。感谢您接受我的答案。亲爱的@Larousso,太好了,哟你最终通过排序实现了你最初的想法。不客气,很高兴与你交流。谢谢你接受我的回答。