Derivar instancias de clase de tipo para clases de caso con exactamente un campo
Estoy trabajando en una biblioteca de análisis CSV (tabular) Utiliza clases de tipo simples para codificar / decodificar: la codificación, por ejemplo, se realiza con instancias deCellEncoder
(para codificar una sola celda) yRowEncoder
(para codificar filas enteras).
Usando sin forma, he encontrado bastante sencillo derivar automáticamente las siguientes instancias de clase de tipo:
RowEncoder[A]
SiA
es una clase de caso cuyos campos tienen todos unCellEncoder
.RowEncoder[A]
SiA
es un ADT cuyas alternativas tienen unRowEncoder
.CellEncoder[A]
SiA
es un ADT cuyas alternativas tienen unCellEncoder
.El caso es que este último resulta ser casi completamente inútil en situaciones de la vida real: las alternativas de un ADT son casi siempre clases de casos, y no puedo derivar unCellEncoder
para una clase de caso que tiene más de un campo.
Sin embargo, lo que me gustaría poder hacer es derivar unCellEncoder
para clases de caso que tienen un solo campo cuyo tipo tiene unCellEncoder
. Eso cubriría, por ejemplo,Either
de scalaz\/
gatosXor
...
Esto es lo que tengo hasta ahora:
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)
})
Esto funciona bien cuando se usa explícitamente:
case class Bar(xs: String)
caseClass1CellEncoder[Bar, String]
res0: tabulate.CellEncoder[Bar] = tabulate.CellEncoder$anon$2@7941904b
Sin embargo, no puedo hacer que funcione implícitamente, lo siguiente falla:
implicitly[CellEncoder[Bar]]
>> could not find implicit value for parameter e: tabulate.CellEncoder[Test.this.Bar]
También probé lo siguiente, sin más éxito:
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)
})
¿Me estoy perdiendo de algo? ¿Es posible lo que intento hacer?