LabelledGeneric с различными типами - PullRequest
0 голосов
/ 11 июня 2018

С учетом этих ADT:

case class SourceRecord(name: String, number: Int)
case class TargetRecord(number: Int, name: String)

Я могу легко сопоставить SourceRecord с TargetRecord:

val sourceGen = LabelledGeneric[SourceRecord]
val targetGen = LabelledGeneric[TargetRecord]
val sourceRecord = SourceRecord("record_1", 1)
val targetRecord = targetGen.from(sourceGen.to(sourceRecord).align[targetGen.Repr])

Однако я изо всех сил пытаюсь понять, как выполнитьпреобразование, если я введу новый тип:

case class MyNumber(value: Int) extends AnyVal
case class SourceRecord(name: String, number: Int)
case class TargetRecord(number: MyNumber, name: String)

Error: could not find implicit value for parameter align: shapeless.ops.hlist.Align[sourceGen.Repr,targetGen.Repr]

Я предполагаю, что мне нужно каким-то образом предоставить класс типов для выравнивания Int с MyNumber, но я не знаю, как.Кто-нибудь может сказать мне?

1 Ответ

0 голосов
/ 14 июня 2018

Вручную вы можете определить его следующим образом:

import shapeless.labelled.FieldType
import shapeless.ops.hlist.Align
import shapeless.record.Record
import shapeless.{::, HNil, Witness}
import shapeless.syntax.singleton._

implicit val align: Align[Record.`'name -> String, 'number -> Int`.T, Record.`'number -> MyNumber, 'name -> String`.T] = {
  case s :: (i: FieldType[Witness.`'number`.T, Int]) :: HNil => 'number ->> MyNumber(i) :: 'name ->> s :: HNil
}
...