我看了一下很酷的 解决办法 由Travis Brown提出的,它允许在通用方式下转换不同的case类。我试着用它来转换 HList
到 case class
但没有设法让它工作。这是我的尝试。
import shapeless._, ops.hlist.Align
import syntax.std.tuple._
object Shplss extends App {
class SameFieldsConverter[T] {
def apply[S, SR <: HList, TR <: HList](s: S)(implicit
genS: LabelledGeneric.Aux[S, SR],
genT: LabelledGeneric.Aux[T, TR],
align: Align[SR, TR]
) = genT.from(align(genS.to(s)))
}
def convertTo[T] = new SameFieldsConverter[T]
type SomeType = Int :: Int :: String :: Boolean :: Int :: Int :: HNil
final case class SomeProductType(f1: Int, f2: Int, f3: String, f4: Boolean, f5: Int, f6: Int)
val some: SomeType = (4, 4, "ssdf", true, 2, 4).productElements
convertTo[SomeProductType](some)
}
不幸的是,它失败的错误。
Error:(22, 29) could not find implicit value for parameter genS: shapeless.LabelledGeneric.Aux[com.test.Shplss.SomeType,SR]
convertTo[SomeProductType](some)
Error:(22, 29) not enough arguments for method apply: (implicit genS: shapeless.LabelledGeneric.Aux[com.test.Shplss.SomeType,SR], implicit genT: shapeless.LabelledGeneric.Aux[com.test.Shplss.SomeProductType,TR], implicit align: shapeless.ops.hlist.Align[SR,TR])com.test.Shplss.SomeProductType in class SameFieldsConverter.
Unspecified value parameters genS, genT, align.
convertTo[SomeProductType](some)
有什么办法可以增强 converTo[B]
函数,所以它可以在 HList
的也是?
Shapeless的 Generic
和 LabelledGeneric
是类型类,它使用hlist和coproducts为case类和密封的性状层次提供了一个通用表示。如果你已经有一个hlist,你并不真正需要一个 Generic
例,而Shapeless没有提供。在你的情况下,这意味着你实际上可以跳过 genS
和 SR
部件。
import shapeless._, ops.hlist.Align
import syntax.std.tuple._
object Shplss extends App {
class SameFieldsConverter[T] {
def apply[S <: HList, TR <: HList](s: S)(implicit
genT: Generic.Aux[T, TR],
align: Align[S, TR]
) = genT.from(align(s))
}
def convertTo[T] = new SameFieldsConverter[T]
type SomeType = Int :: Int :: String :: Boolean :: Int :: Int :: HNil
final case class SomeProductType(f1: Int, f2: Int, f3: String, f4: Boolean, f5: Int, f6: Int)
val some: SomeType = (4, 4, "ssdf", true, 2, 4).productElements
convertTo[SomeProductType](some)
}
这将给你 SomeProductType(4,4,ssdf,true,2,4)
,正如你所期望的那样。
请注意,我已经改变了 genT
从 LabelledGeneric
到 Generic
因为我们不再有标签来对齐输入端。我想你可以添加一些额外的机制来 "注入 "无标签的输入到Shapeless记录中以匹配 LabelledGeneric
类型,但在这个特定的用例中,至少没有任何意义。