简体   繁体   English

有没有办法以通用方式将 Hlist 转换为适当的案例 class ?

[英]Is there a way to convert Hlist to an appropriate case class in a generic way?

I have looked at the cool solution presented by Travis Brown which allows converting case classes between each other in a generic way.我看过 Travis Brown 提出的很酷的解决方案,它允许以通用方式在彼此之间转换案例类。 I tried to use it to convert HList to a case class but did not managed to get it worked.我尝试使用它将HList转换为case class ,但没有成功。 Here is my attempt:这是我的尝试:

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)
}

Unfortunately it fails with the error:不幸的是,它失败并出现错误:

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)

Is there a way to enhance the converTo[B] function so it can convert between HList s as well?有没有办法增强 converTo converTo[B] function 以便它也可以在HList之间转换?

Shapeless's Generic and LabelledGeneric are type classes that provide a generic representation for case classes and sealed trait hierarchies using hlists and coproducts. Shapeless 的GenericLabelledGeneric是类型类,它们使用 hlists 和 coproducts 为案例类和密封特征层次结构提供通用表示。 If you already have an hlist, you don't really need a Generic instance, and Shapeless doesn't provide one.如果您已经有一个 hlist,那么您实际上并不需要Generic实例,Shapeless 也不提供。 In your case this means you can actually skip the genS and SR parts:在您的情况下,这意味着您实际上可以跳过genSSR部分:

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)
}

This will give you SomeProductType(4,4,ssdf,true,2,4) , as you'd expect.正如您所期望的,这将为您提供SomeProductType(4,4,ssdf,true,2,4)

Note that I've changed genT from LabelledGeneric to Generic , since we no longer have labels to align on the input side.请注意,我已将genTLabelledGeneric更改为Generic ,因为我们不再需要在输入端对齐标签。 I guess you could add some extra machinery to "inject" the unlabeled input into a Shapeless record to match the LabelledGeneric type, but in this specific use case at least there's not really any point.我想您可以添加一些额外的机制来将未标记的输入“注入”到无形记录中以匹配LabelledGeneric类型,但在这个特定的用例中至少没有任何意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无形:有没有办法从案例类或元组中获取Hlist类型 - Shapeless: is there a way to get Hlist type from a case class or a tuple 无形转换案例类到HList并跳过所有选项字段 - shapeless convert case class to HList and skip all option fields Scala无形:如何将hlist.Mapper转换为案例类? - Scala shapeless: how to convert a hlist.Mapper to a case class? 在 scala shapeless 库中,是否有一种本机方法可以将产品类型(HList/Generic/NamedGeneric)转换为与其数量相等的 int 单例类型? - In scala shapeless library, is there a native way to convert a product type (HList/Generic/NamedGeneric) to an int singleton type equal to its arity? 反转 HList 并转换为类? - Reverse HList and convert to class? 如何将通用HList转换为List - How to convert a generic HList to a List 以类型安全的方式将Seq [String]转换为case类 - Convert a Seq[String] to a case class in a typesafe way 在Scala中,有一种简单的方法可以将案例类转换为元组吗? - In Scala, is there an easy way to convert a case class into a tuple? 使用无形通过HList将Future的元组转换为元组的Future - Using shapeless to convert tuple of Future to Future of tuple by way of HList 如何通过shapeless将case类转换为HList而不是修改再创建case类? - How to convert case class to HList than to modify than to create case class again by shapeless?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM