首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将HList转换为另一个HList

将HList转换为另一个HList
EN

Stack Overflow用户
提问于 2019-12-11 06:25:44
回答 1查看 49关注 0票数 2

我正在尝试通过转换为HList来将case类转换为另一个类。

代码语言:javascript
复制
case class Source(p1:S1, p2:S2) -> HList[S1:+:S2] -> HList[D1:+:D2] ->case class Destination(p1:D1,p2:D2)

我可以通过gem.to从源文件转换为HList文件,通过gen.from文件从HList文件转换为目标文件。我为Source上的每种类型的参数编写了一个转换器,将其转换为Destination中的相应类型,但我不确定如何递归遍历HList。我的尝试显示在下面的hlistEncoder

代码语言:javascript
复制
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)
    }

  }

}

我使用此方法来测试从HList到HList的转换

代码语言:javascript
复制
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)

您对如何实现hlistEncoder有什么想法吗

EN

回答 1

Stack Overflow用户

发布于 2019-12-11 07:33:50

我猜你已经

代码语言:javascript
复制
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
}

您希望您的类型类ConverterT转换为Datastructure。而且(HList[S1:+:S2] -> HList[D1:+:D2],我猜应该是::而不是:+:)您希望将HList的子类型转换为HList的子类型(而不是HList本身,否则Generic无法恢复case类)。因此,要么您应该修改您的类型类

代码语言:javascript
复制
trait Converter[T] {
  type Out
  def convert(t:T): Out
}

或者您需要两个类型类:原始Converter

代码语言:javascript
复制
trait HListConverter[T <: HList] {
  type Out <: HList
  def convert(t:T): Out
}

此外,目前您的Converter相当粗糙。它将每个T转换为Datastructure,而不是Datastructure的特定子类型。这意味着Generic将只能恢复形状的案例类

代码语言:javascript
复制
MyClass(x: Datastructure) 
MyClass(x: Datastructure, y: Datastructure) 
...

这真的是你想要的吗?如果是这样,那么好吧,如果不是,你需要

代码语言:javascript
复制
MyClass(x: Str) 
MyClass(x: Num, y: Incc) 
...

然后你又需要

代码语言:javascript
复制
trait Converter[T] {
  type Out
  def convert(t:T): Out
}

您可以使用标准shapeless.ops.hlist.Mapper而不是HListConverter

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59276266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档