Получение экземпляров классов типов для классов случаев с ровно одним полем
Я работаю над библиотекой разбора CSV (пластинчатый). Для кодирования / декодирования используются классы простых типов: например, кодирование выполняется с экземплярамиCellEncoder
(для кодирования одной ячейки) иRowEncoder
(для кодирования целых строк).
Используя бесформенное, я обнаружил, что довольно просто автоматически получить следующие экземпляры классов типов:
RowEncoder[A]
еслиA
это класс case, все поля которого имеютCellEncoder
.RowEncoder[A]
еслиA
это ADT, чьи альтернативы имеютRowEncoder
.CellEncoder[A]
еслиA
это ADT, чьи альтернативы имеютCellEncoder
.Дело в том, что последний из них оказывается практически совершенно бесполезным в реальных жизненных ситуациях: альтернативы ADT - это почти всегда case-классы, и я не могу получитьCellEncoder
для класса дела, который имеет более одного поля.
Однако я хотел бы иметь возможность получитьCellEncoder
для классов случаев, которые имеют одно поле, тип которого имеетCellEncoder
, Это будет охватывать, например,Either
Скаляш\/
кошачьиXor
...
Это то, что я до сих пор:
implicit def caseClass1CellEncoder[A, H](implicit gen: Generic.Aux[A, H :: HNil], c: CellEncoder[H]): CellEncoder[A] =
CellEncoder((a: A) => gen.to(a) match {
case h :: t => c.encode(h)
})
Это прекрасно работает, когда используется явно:
case class Bar(xs: String)
caseClass1CellEncoder[Bar, String]
res0: tabulate.CellEncoder[Bar] = tabulate.CellEncoder$anon$2@7941904b
Однако я не могу заставить его работать неявно, следующее не получается:
implicitly[CellEncoder[Bar]]
>> could not find implicit value for parameter e: tabulate.CellEncoder[Test.this.Bar]
Я также попробовал следующее, но безуспешно:
implicit def testEncoder[A, H, R <: H :: HNil](implicit gen: Generic.Aux[A, R], c: CellEncoder[H]): CellEncoder[A] =
CellEncoder((a: A) => gen.to(a) match {
case h :: t => c.encode(h)
})
Я что-то пропустил? Возможно ли то, что я пытаюсь сделать?