scala - 在函数内映射 HList

标签 scala shapeless type-level-computation hlist

下面的代码似乎很明显可以编译和运行

case class Pair(a: String, b: Int)

val pairGen = Generic[Pair]

object size extends Poly1 {
  implicit def caseInt = at[Int](x => 1)
  implicit def caseString = at[String](_.length)
}

def funrun(p: Pair) = { 
  val hp: HList = pairGen.to(p)
  hp.map(size)
}

但是编译器说“找不到参数映射器的隐式值”。在我的用例中,我想映射 HList 以获取 String(s) 的 HList,然后将 String(s) 的 HList 转换为 Scala List[String]。有任何想法吗?

最佳答案

首先我们可以创建一个 Poly1类似于 size我们可以用它来映射 HListHListStrings .

object strings extends Poly1 {
  implicit def caseInt = at[Int](_.toString)
  implicit def caseString = at[String](identity)
}

您已经在使用 Generic[Pair]转一个 PairHList ,但您无法映射您的 hp因为你的funrun没有证据你可以映射它。我们可以通过使用隐式参数来解决这个问题。
def funRun[L <: HList, M <: HList](
  p: Pair
)(implicit
  gen: Generic.Aux[Pair, L],
  mapper: Mapper.Aux[strings.type, L, M]
) = gen.to(p).map(strings)
  • 我们的第一个隐式参数 gen可以转一个PairHList类型 L .
  • 我们的第二个隐式参数 mapper可以使用我们的strings映射 HList 的多态函数类型 LHList类型 M .

  • 我们现在可以使用 funRun转一个 PairHListStrings :
    scala> funRun(Pair("abc", 12))
    res1: shapeless.::[String,shapeless.::[String,shapeless.HNil]] = abc :: 12 :: HNil
    

    但是你想返回一个 List[String] .转我们的HList M (映射到 String 的结果)到 List[String]我们需要一个 ToTraversable ,所以我们添加了第三个隐式参数:
    import shapeless._, ops.hlist._
    
    def pairToStrings[L <: HList, M <: HList](
      p: Pair
    )(implicit
      gen: Generic.Aux[Pair, L],
      mapper: Mapper.Aux[strings.type, L, M],
      trav: ToTraversable.Aux[M,List,String]
    ): List[String] = gen.to(p).map(strings).toList
    

    我们可以将其用作:
    scala> pairToStrings(Pair("abc", 12))
    res2: List[String] = List(abc, 12)
    

    关于scala - 在函数内映射 HList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32447709/

    相关文章:

    scala - 为什么在 spark 中创建数据集需要编码器

    ScalaTest runner + FunSuite + 标签 : can't get `-n` and `-l` to include/exclude tag?

    scala - 我希望我的函数返回 Stream[T],但我不知道如何进行类型检查

    scala - 如何将通用 HList 转换为列表

    haskell - 我可以静态拒绝存在类型的不同实例吗?

    json - 如何将JSON空值解码为空集合

    scala - 在 Scala 中添加整数元组列表

    scala - Shapeless 是否使用反射,在 Scala 生产代码中使用是否安全?

    haskell - 将类型级别列表转换为值

    scala - 有哪些类型级编程的例子?