Shapeless - Generic в общем контексте - PullRequest
0 голосов
/ 12 марта 2019

Это вопрос из поста, который я сделал сегодня.

Я работаю с HList и Generic в надежде выполнить неявное преобразование между классами case.

Рассмотрим:

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

Я могу конвертировать между двумя типами очень просто:

Generic[B].from(Generic[A].to(A(1, 2.0, true)).tail) // B(2.0, true)

Я хочу иметь возможность наложить метод на Product, чтобы я мог сделать следующее:

A(1, 2.0, true).to[B]

Моя попытка выглядит следующим образом:

object ShapelessTest extends App {

  implicit class convert[From <: Product, FromHListT <: HList]
    (x: From)(implicit genFrom: Generic.Aux[From, FromHlistT]){

    def to[To <: Product, ToHlistT <: HList]
      (implicit genTo: Generic.Aux[To, ToHilstT]): To = {

      val fromHList = genFrom.to(x)

      val toHList = ??? // Manipulate toHList to correspond with type ToHListT

      genTo.from(toHList)
    }
  }

  println(C(1, 2.0, true).to[D, Double :: Boolean :: HNil])
}

Теперь мой код не идеален по двум причинам.

  1. Я должен явно указать тип To HList.

  2. Мне нужно манипулировать экземпляром FromHListT (возможно, выбирая значения по индексу), а затем убедиться, что он имеет тип ToHListT.

У кого-нибудь есть советы, как мне получить Generic.Aux [T, ToHListT] без указания параметра второго типа?

  1. Может кто-нибудь посоветовать, как я могу манипулировать (удалять элементы, переупорядочивать FromHListT) и конвертировать в экземпляр ToHListT.

1 Ответ

0 голосов
/ 12 марта 2019

Вам следует прочитать главу «6.3 Изучение конкретного случая: миграция классов случаев» в «Руководстве астронавта Type to Shapeless» https://books.underscore.io/shapeless-guide/shapeless-guide.html#sec:ops:migration

Обычно, когда вы хотите скрыть дополнительные шаблоны, вы вводите класс типов.

Также вместо неявного g: Generic.Aux[A, B] вы можете попробовать использовать неявное g: Generic[A] и набрать g.Repr вместо B.

...