有没有办法以通用方式将 Hlist 转换为适当的大小写 class ?
Is there a way to convert Hlist to an appropriate case class in a generic way?
我看过 Travis Brown 提出的很酷的 ,它允许以通用方式在彼此之间转换大小写 类。我试图用它来将 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 和联积为案例 类 和密封特征层次结构提供通用表示。如果您已经有一个 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
,因为我们不再需要在输入端对齐标签。我想你可以添加一些额外的机制到 "inject" 未标记的输入到无形记录中以匹配 LabelledGeneric
类型,但至少在这个特定的用例中没有任何意义。
我看过 Travis Brown 提出的很酷的 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 和联积为案例 类 和密封特征层次结构提供通用表示。如果您已经有一个 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
,因为我们不再需要在输入端对齐标签。我想你可以添加一些额外的机制到 "inject" 未标记的输入到无形记录中以匹配 LabelledGeneric
类型,但至少在这个特定的用例中没有任何意义。