Deriving type class instances for case classes with exactly one field

梦想的初衷 提交于 2019-12-03 15:35:06

It's a little tricky to get the H inferred correctly, but you can do it with a <:< instance:

import shapeless._

case class CellEncoder[A](encode: A => String)

implicit val stringCellEncoder: CellEncoder[String] = CellEncoder(identity)
implicit val intCellEncoder: CellEncoder[Int] = CellEncoder(_.toString)

case class Bar(xs: String)

implicit def caseClass1CellEncoder[A, R, H](implicit
  gen: Generic.Aux[A, R],
  ev: R <:< (H :: HNil),
  c: CellEncoder[H]
): CellEncoder[A] = CellEncoder(
  (a: A) => ev(gen.to(a)) match {
    case h :: t => c.encode(h)
  }
)

(I've made up a simple CellEncoder for the sake of a complete working example.)

This works because R can be inferred when the compiler is looking for an Generic.Aux[A, R] instance, and can then guide the inference of H when looking for a value for ev.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!