Getting instances of a single-field case class decoder

This question is closely related to this , but not identical: it is the same context, but the opposite problem.

I am trying to get CellDecoder[A] , which is essentially String => A , for A , which are case classes with a single field of type CellDecoder .

For this I need:

  • A can be converted to R , where R is a subtype of H :: HNil .
  • H have an instance of CellDecoder .

I.e:

 implicit def caseClassCellDecoder[A, R, H](implicit gen: Generic.Aux[A, R], ev: R <:< (H :: HNil), d: CellDecoder[H] ): CellDecoder[A] = ??? 

The problem I am facing is that after I turned String into H via the corresponding CellDecoder instance, I was kind of stuck: ev allows me to convert R to H :: HNil , but not H :: HNil to R . Without R , I cannot use my Generic.Aux[A, R] to get the final copy of A

It turns out that my H :: HNil in R works, but I'm not sure why and cannot convince myself that this will always be so.

I thought that R should be strictly equal to H :: HNil (i.e., have R =:= HNil ), but then the implications cannot be resolved.

Is there a way to do what I'm trying to do?

+1
source share
1 answer

I used =:= instead of <:< , but swapped the sides of R and H::HNil and seemed to work:

 case class CellDecoder[A](decode: String => A) implicit val stringCellDecoder: CellDecoder[String] = CellDecoder(identity) implicit def caseClassCellDecoder[A, R, H](implicit gen: Generic.Aux[A, R], ev: (H :: HNil) =:= R, d: CellDecoder[H] ): CellDecoder[A] = CellDecoder( (str: String) => gen.from(ev(d.decode(str)::HNil)) ) 

Therefore, I was able to use it as follows:

 case class TestDecoder(test: String) def doDecode[A: CellDecoder](str: String): A = { implicitly[CellDecoder[A]].decode(str) } doDecode[TestDecoder]("encoded value") 
+2
source

Source: https://habr.com/ru/post/1235352/


All Articles