[英]transform HList into another HList
I'm trying to convert a case class into another via conversion to HList.我正在尝试通过转换为 HList 将案例类转换为另一个案例类。
case class Source(p1:S1, p2:S2) -> HList[S1:+:S2] -> HList[D1:+:D2] ->case class Destination(p1:D1,p2:D2)
I can convert from Source to HList via gem.to and from HList to Destination via gen.from.我可以通过 gem.to 从 Source 转换为 HList,通过 gen.from 从 HList 转换为 Destination。 I wrote a Converter for each type of parameter on Source to convert it to its corresponding type in Destination but I am unsure how to recursively traverse the HList.
我为 Source 上的每种类型的参数编写了一个转换器,以将其转换为 Destination 中的相应类型,但我不确定如何递归遍历 HList。 My attempt is shown below in
hlistEncoder
我的尝试显示在
hlistEncoder
下面
trait Converter[T] {
def convert(t:T): Datastructure
}
object Converter {
implicit object StrDatastructure extends Converter[String]{
def convert(t:String) = Datastructure.Str(t)
}
implicit object NumDatastructure extends Converter[Double]{
def convert(t :Double) = Datastructure.Num(t)
}
implicit object IncDatastructure extends Converter[Inc]{
def convert(t :Inc) = Datastructure.Incc(t)
}
implicit def SeqDatastructure[T: Converter]: Converter[Seq[T]] = new Converter[Seq[T]]{
def convert(t: Seq[T]) = {
Datastructure.Listt(t.map(implicitly[Converter[T]].convert):_*)
}
}
//HList traversals
implicit object hnilDatastructure extends Converter[HNil]{
def convert(t: HNil) = Datastructure.Hnill(t)
}
implicit def hlistEncoder[H, T <: HList](implicit
hEncoder: Converter[H],
tEncoder: Converter[T]
): Converter[H :: T] = new Converter[H :: T] {
def apply(h:H, t:T)= {
case (h :: t) => hEncoder.convert(h) ++ tEncoder.convert(t)
}
}
}
I use this method to test HList to HList conversion我用这个方法来测试 HList 到 HList 的转换
def convertToDatastructureN[T](x: T)(implicit converter: Converter[T]): Datastructure = {
converter.convert(x)
}
case class Inc(i:Int)
case class Source(i: Int, n:Inc)
val x = Generic[Source]
val xHlist = x.to(Source(99, Inc(5)))
convertToDatastructureN(xHlist)
Any ideas how to implement hlistEncoder
?任何想法如何实现
hlistEncoder
?
I guess you have我猜你有
sealed trait Datastructure
object Datastructure {
case class Str(t: String) extends Datastructure
case class Num(t: Double) extends Datastructure
case class Incc(t: Inc) extends Datastructure
case class Listt(t: Datastructure*) extends Datastructure
case class Hnill(t: HNil) extends Datastructure
}
You want your type class Converter
to transform T
into Datastructure
.您希望您的类型类
Converter
将T
转换为Datastructure
。 But also ( HList[S1:+:S2] -> HList[D1:+:D2]
, where I guess ::
should be instead of :+:
) you want subtypes of HList
to be transformed into subtypes of HList
(not into HList
itself since otherwise Generic
can't restore case class).而且(
HList[S1:+:S2] -> HList[D1:+:D2]
,我猜::
应该代替:+:
)您希望HList
子类型转换为HList
子类型(而不是HList
本身,否则Generic
无法恢复 case 类)。 So either you should modify your type class所以要么你应该修改你的类型类
trait Converter[T] {
type Out
def convert(t:T): Out
}
or you need two type classes: your original Converter
and或者你需要两个类型类:你原来的
Converter
和
trait HListConverter[T <: HList] {
type Out <: HList
def convert(t:T): Out
}
Moreover, currently your Converter
is pretty rough.此外,目前您的
Converter
非常粗糙。 It transforms every T
into Datastructure
instead of into specific subtypes of Datastructure
.它把每一个
T
到Datastructure
,而不是插入的特定亚型Datastructure
。 This means Generic
will be able to restore case classes only of shapes这意味着
Generic
将能够仅恢复形状的案例类
MyClass(x: Datastructure)
MyClass(x: Datastructure, y: Datastructure)
...
Is it really what you want?真的是你想要的吗? If so then ok, if not and you need
如果是,那么可以,如果不是,你需要
MyClass(x: Str)
MyClass(x: Num, y: Incc)
...
then again you need然后你又需要
trait Converter[T] {
type Out
def convert(t:T): Out
}
Instead of HListConverter
you can use standard shapeless.ops.hlist.Mapper
.取而代之的
HListConverter
你可以使用标准shapeless.ops.hlist.Mapper
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.