我正在研究CSV解析庫(tabulate)。它使用簡單的類型進行編碼/解碼:例如,編碼通過CellEncoder
(編碼單個單元)和RowEncoder
(編碼整行)的實例完成。爲僅具有一個字段的案例類派生類型類實例
使用不成形,我發現它非常簡單的自動導出以下類型的類實例:
RowEncoder[A]
如果A
是一個案例類,其字段都有CellEncoder
。RowEncoder[A]
如果A
是ADT,其替代品全部具有RowEncoder
。CellEncoder[A]
如果A
是ADT,其替代品全部具有CellEncoder
。
的事情是,這最後的一個結果是在現實生活中幾乎完全無用的:一個ADT的替代品幾乎都是case類,我不能爲具有多個字段的情況下,類派生一個CellEncoder
。
但是,我希望能夠做的,是派生一個CellEncoder
案件類別,其中有一個單一字段的類型有CellEncoder
。這將包括,例如,Either
,scalaz的\/
,貓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] = [email protected]
但我不能隱含起作用,下面的失敗:
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)
})
我缺少的東西?我試圖做甚至可能嗎?
我需要長時間思考這個問題,但我可以證實它是有效的。巧合的是,我在Circe的代碼中花了很多時間來理解案例類的自動類型派生,所以謝謝你的答案和Circe! –
我正在努力解決這個問題 - 編寫一個CellDecoder('String => A'),因爲R <:
@NicolasRinaudo一個新問題是適當的。 –