7

次のコードは、コンパイルして実行するのに十分明らかなようです

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 をマップして文字列の HList を取得し、次に文字列の HList を Scala List[String] に変換します。何か案は?

4

1 に答える 1

12

最初に、 を から にマップするために使用できる類似のPoly1を作成できます。sizeHListHListStrings

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

を に変換するために既に を使用Generic[Pair]していPairましたが、 をマッピングできるという証拠がないため、HListをマッピングできませんでした。これは、暗黙のパラメーターを使用して解決できます。hpfunrun

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は、 aPairHList of 型に変えることができますL
  • 2 番目の暗黙のパラメーターmapperは、多態性関数を使用してof 型をof型stringsにマップできます。HListLHListM

a をofに変換するために使用できるようfunRunになりPairました:HListStrings

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

しかし、あなたは を返したかったのList[String]です。(へHList Mのマッピングの結果String) をに変換するには、List[String]が必要なToTraversableので、3 つ目の暗黙のパラメーター を追加します。

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)
于 2015-09-08T09:34:33.353 に答える