使用单个字段派生 case 类 的解码器实例
Deriving decoder instances of case classes with a single field
此问题与 密切相关,但不完全相同:上下文相同但问题相反。
我正在尝试导出一个 CellDecoder[A]
,它本质上是一个 String => A
,对于大小写 类 的 A
,其类型为CellDecoder
.
为此,我需要要求:
A
可转换为 R
,其中 R
是 H :: HNil
. 的子类型
H
有 CellDecoder
个实例。
即:
implicit def caseClassCellDecoder[A, R, H](implicit
gen: Generic.Aux[A, R],
ev: R <:< (H :: HNil),
d: CellDecoder[H]
): CellDecoder[A] = ???
我遇到的问题是,一旦我通过相关 CellDecoder
实例将 String
转换为 H
,我就有点卡住了:ev
允许我将 R
转换为 H :: HNil
,但不能将 H :: HNil
转换为 R
。没有 R
,我无法使用我的 Generic.Aux[A, R]
获得最终的 A
实例。
事实证明,将我的 H :: HNil
转换为 R
是可行的,但我不确定为什么,也无法说服自己永远如此。
我考虑过要求 R
严格等于 H :: HNil
(即有一个 R =:= HNil
),但是隐式无法解析。
有没有办法做我想做的事?
我确实使用了 =:=
而不是 <:<
但是交换了 R
和 H::HNil
的边,这似乎有效:
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))
)
所以我能够按如下方式使用它:
case class TestDecoder(test: String)
def doDecode[A: CellDecoder](str: String): A = {
implicitly[CellDecoder[A]].decode(str)
}
doDecode[TestDecoder]("encoded value")
此问题与
我正在尝试导出一个 CellDecoder[A]
,它本质上是一个 String => A
,对于大小写 类 的 A
,其类型为CellDecoder
.
为此,我需要要求:
A
可转换为R
,其中R
是H :: HNil
. 的子类型
H
有CellDecoder
个实例。
即:
implicit def caseClassCellDecoder[A, R, H](implicit
gen: Generic.Aux[A, R],
ev: R <:< (H :: HNil),
d: CellDecoder[H]
): CellDecoder[A] = ???
我遇到的问题是,一旦我通过相关 CellDecoder
实例将 String
转换为 H
,我就有点卡住了:ev
允许我将 R
转换为 H :: HNil
,但不能将 H :: HNil
转换为 R
。没有 R
,我无法使用我的 Generic.Aux[A, R]
获得最终的 A
实例。
事实证明,将我的 H :: HNil
转换为 R
是可行的,但我不确定为什么,也无法说服自己永远如此。
我考虑过要求 R
严格等于 H :: HNil
(即有一个 R =:= HNil
),但是隐式无法解析。
有没有办法做我想做的事?
我确实使用了 =:=
而不是 <:<
但是交换了 R
和 H::HNil
的边,这似乎有效:
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))
)
所以我能够按如下方式使用它:
case class TestDecoder(test: String)
def doDecode[A: CellDecoder](str: String): A = {
implicitly[CellDecoder[A]].decode(str)
}
doDecode[TestDecoder]("encoded value")