本文介绍了在函数内映射 HList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码看起来很明显,可以编译和运行

The following code seems obvious enough to compile and run

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].有任何想法吗?

but the compiler says "could not find implicit value for parameter mapper". In my use case, I want to map over an HList to get and HList of String(s) and then convert the HList of String(s) into Scala List[String]. Any ideas?

推荐答案

首先我们可以创建一个类似于 sizePoly1,我们可以用它来映射一个 HListStringsHList.

First we can create a Poly1 similar to size which we can use to map an HList to an HList of Strings.

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

您已经在使用 Generic[Pair]Pair 转换为 HList,但是您无法映射您的 hp 因为在您的 funrun 中没有证据表明您可以对其进行映射.我们可以通过使用隐式参数来解决这个问题.

You were already using Generic[Pair] to turn a Pair into an HList, but you couldn't map over your hp because there is no evidence in your funrun that you can map over it. We can solve this by using implicit parameters.

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 可以将 Pair 转换为 HListL 类型.
  • 我们的第二个隐式参数 mapper 可以使用我们的 strings 多态函数将 L 类型的 HList 映射到M 类型的 HList.
    • Our first implicit parameter gen can turn a Pair into an HListof type L.
    • Our second implicit parameter mapper can use our strings polymorphic function to map an HList of type L to an HList of type M.
    • 我们现在可以使用 funRunPair 转换为 StringsHList :

      We can now use funRun to turn a Pair into an HList of Strings :

      scala> funRun(Pair("abc", 12))
      res1: shapeless.::[String,shapeless.::[String,shapeless.HNil]] = abc :: 12 :: HNil
      

      但是你想返回一个List[String].要将我们的 HList M(映射到 String 的结果)转换为 List[String],我们需要一个ToTraversable,所以我们添加了第三个隐式参数:

      But you wanted to return a List[String]. To turn our HList M (the result of mapping to String) to a List[String] we need a ToTraversable, so we add a third implicit parameter :

      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)
      

      这篇关于在函数内映射 HList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 08:25