Typklasseninstanzen für Fallklassen mit genau einem Feld ausführen
Ich arbeite an einer CSV-Parsing-Bibliothek tabulate). Es werden einfache Typklassen zum Codieren / Decodieren verwendet: Das Codieren wird beispielsweise mit Instanzen von @ durchgeführCellEncoder
(um eine einzelne Zelle zu kodieren) undRowEncoder
(um ganze Zeilen zu kodieren).
Unter Verwendung von shapeless habe ich festgestellt, dass es ziemlich einfach ist, die folgenden Typklasseninstanzen automatisch abzuleiten:
RowEncoder[A]
wennA
ist eine Fallklasse, deren Felder alle ein @ habCellEncoder
.RowEncoder[A]
wennA
ist ein ADT, dessen Alternativen alle ein @ habRowEncoder
.CellEncoder[A]
wennA
ist ein ADT, dessen Alternativen alle ein @ habCellEncoder
.Die Sache ist, dass sich letzteres in realen Situationen als fast völlig nutzlos herausstellt: Die Alternativen eines ADT sind fast immer Fallklassen, und ich kann kein @ ableiteCellEncoder
für eine Fallklasse mit mehr als einem Feld.
Was ich aber gerne tun würde, ist ein @ abzuleitCellEncoder
für Fallklassen, die ein einzelnes Feld haben, dessen Typ ein @ hCellEncoder
. Das würde zum Beispiel abdecken,Either
, scalaz's\/
, KatzenXor
...
Das ist, was ich bisher habe:
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)
})
Dies funktioniert gut, wenn es explizit verwendet wird:
case class Bar(xs: String)
caseClass1CellEncoder[Bar, String]
res0: tabulate.CellEncoder[Bar] = tabulate.CellEncoder$anon$2@7941904b
Ich kann es jedoch nicht implizit zum Laufen bringen, Folgendes schlägt fehl:
implicitly[CellEncoder[Bar]]
>> could not find implicit value for parameter e: tabulate.CellEncoder[Test.this.Bar]
Ich habe auch folgendes probiert, ohne mehr Erfolg:
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)
})
Bin ich etwas vermisst? Ist das, was ich versuche, überhaupt möglich?