Shapeless - программно удалить поля из класса case, используя LabelledGeneric - PullRequest
1 голос
/ 12 марта 2019

У меня проблемы с преобразованием между классами дел с использованием LabelledGeneric

Ниже приведен упрощенный пример моего кода:

import shapeless._
import shapeless.record._

  def removeKeys[
    F <: Product,
    T <: Product,
    HF <: HList,
    HT <: Product
  ](
    from: F,
    removeField: String
  )(
    implicit genericFrom: LabelledGeneric.Aux[F, HF],
    genericTo: LabelledGeneric.Aux[T, HT]
  ): T = {
    val hListFrom = genericFrom.to(from) 
    val hListTo = hListFrom - Witness(removeField) // Missing implicit Remover 
    genericTo.from(hListTo) // If I remove multiple fields in a say foldLeft how do I ensure the resulting HList is of type HT?
  }

Я явно пропускаю Remover - как мне его вызвать?если учесть, что я в конечном итоге захочу свернуть элемент над набором меток, чтобы удалить hListFrom?

Мое конечное намерение состоит в том, чтобы выбрать все поля из класса F, которые существуют в классе T с таким же типом.

Например, учитывая:

case class A(a: Int, b: Double, c: Boolean)
case class B(b: Double, c: Boolean)

Я хочу

def f[F <: Product, T <: Product](cc: F): T

, чтобы f(A(1, 1.0, true)) вернул B(1.0, true)

Я думаю, мне нужно пересечениеоднако два HList мне пришло в голову, что мне нужно изменить порядок в зависимости от порядка параметров конструктора класса выходного случая.

Мне нравится изучать Shapeless, но есть довольно крутая кривая обучения и многиеиз примеров, как правило, опускаются подробности о том, как обеспечить передачу последствий в общий код.

1 Ответ

1 голос
/ 12 марта 2019

Относительно вашей первой части вопроса,

  import shapeless._
  import shapeless.ops.record.Remover
  import shapeless.record._

  def removeKeys[
  F <: Product,
  T <: Product,
  HF <: HList,
  HT <: HList,
  V
  ](
     from: F,
     removeField: Witness
   )(
     implicit genericFrom: LabelledGeneric.Aux[F, HF],
     remover: Remover.Aux[HF, removeField.T, (V, HT)],
     genericTo: LabelledGeneric.Aux[T, HT],
  ): T = {
    val hListFrom = genericFrom.to(from)
    val hListTo = hListFrom - removeField
    genericTo.from(hListTo)
  }
...