这个问题与this one密切相关,但不完全相同:它是相同的背景,但却是相反的问题。
我试图为CellDecoder[A]
派生一个String => A
,其本质上是A
,它是一个案例类,其中一个字段的类型为{{1} }}
为了做到这一点,我需要:
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] = ???
个实例将String
变为H
,我就会受到欢迎卡住:CellDecoder
允许我将ev
转换为R
,而不是H :: HNil
转换为H :: HNil
。没有R
,我无法使用R
获取最终Generic.Aux[A, R]
个实例。
事实证明,将我的A
投放到H :: HNil
作品中,但我不确定原因,并且无法说服自己,事情总是如此
我考虑过要求R
严格等于R
(也就是说,要H :: HNil
),但这意味着无法解决。
有没有办法做我想做的事情?
答案 0 :(得分:2)
我确实使用了=:=
而不是<:<
但是交换了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")