将 Sized[Something[String], _] 集合转换为 HList
Convert Sized[Something[String], _] collection to HList
我是 shapeless 的新手,正在尝试边做边学。我想制作一个非常小的库,它可以将 String 的集合(第一步是 Sized 集合)转换为不同类型的 HList。
基本上我想要达到的目标:
import shapeless._
import nat._
import BigQueryParser._
val s: Sized[IndexedSeq[String], nat._3] = Sized("Testing", "2.0", "1")
BigQueryParser[Sized[IndexedSeq[String], nat._3], String :: BigDecimal :: BigInt :: HNil].parse(s)
我的非工作实现在这里https://gist.github.com/taojang/f6a9352dbc618039e3a3
之后实现的
我的代码无法编译,编译器抱怨以下错误:
[error] /somepath/some-file.scala: could not find implicit value for parameter st: exmaple.BigQueryParser[shapeless.Sized[IndexedSeq[String],shapeless.nat._3],shapeless.::[String,shapeless.::[BigDecimal,shapeless.::[BigInt,shapeless.HNil]]]]
[error] BigQueryParser[Sized[IndexedSeq[String], nat._3], String :: BigDecimal :: BigInt :: HNil].parse(s)
我发现调试此类问题的最佳方法是尝试手动构建您的实例。例如,这很好:
scala> BigQueryParser[Sized[IndexedSeq[String], _0], HNil]
res0: BigQueryParser[shapeless.Sized[IndexedSeq[String],shapeless.nat._0],shapeless.HNil] = BigQueryParser$$anon@2f4cd46d
但这会中断:
scala> deriveHCons[IndexedSeq[String], _0, String, HNil]
<console>:31: error: could not find implicit value for parameter conv: BigQueryParser[scala.collection.generic.IsTraversableLike[IndexedSeq[String]]#A,String]
deriveHCons[IndexedSeq[String], _0, String, HNil]
^
这表明 IsTraversableLike[Repr]#A
类型的投影出了问题。在这种情况下,我要做的第一件事就是将其设为类型参数(在本例中为 ReprA
),然后使用细化类型约束 IsTraversableLike[Repr]
实例:
implicit def deriveHCons[Repr, ReprA, L <: Nat, V, T <: HList](implicit
itl: IsTraversableLike[Repr] { type A = ReprA },
ev: AdditiveCollection[Repr],
ts: BigQueryParser[Sized[Repr, L], T],
conv: BigQueryParser[ReprA, V]
): BigQueryParser[Sized[Repr, Succ[L]], V :: T] =
new BigQueryParser[Sized[Repr, Succ[L]], V :: T] {
def parse(s: Sized[Repr, Succ[L]]): Try[V :: T] =
for {
h <- conv.parse(s.head)
t <- ts.parse(s.tail)
} yield h :: t
}
这很好用:
scala> println(
| BigQueryParser[
| Sized[IndexedSeq[String], nat._3],
| String :: BigDecimal :: BigInt :: HNil
| ].parse(s)
| )
Success(Testing :: 2.0 :: 1 :: HNil)
您可能还可以进行其他简化(例如,直接使用 _0
而不是 L <: _0
类型参数),但此修复至少应该让事情顺利进行。
我是 shapeless 的新手,正在尝试边做边学。我想制作一个非常小的库,它可以将 String 的集合(第一步是 Sized 集合)转换为不同类型的 HList。
基本上我想要达到的目标:
import shapeless._
import nat._
import BigQueryParser._
val s: Sized[IndexedSeq[String], nat._3] = Sized("Testing", "2.0", "1")
BigQueryParser[Sized[IndexedSeq[String], nat._3], String :: BigDecimal :: BigInt :: HNil].parse(s)
我的非工作实现在这里https://gist.github.com/taojang/f6a9352dbc618039e3a3
之后实现的我的代码无法编译,编译器抱怨以下错误:
[error] /somepath/some-file.scala: could not find implicit value for parameter st: exmaple.BigQueryParser[shapeless.Sized[IndexedSeq[String],shapeless.nat._3],shapeless.::[String,shapeless.::[BigDecimal,shapeless.::[BigInt,shapeless.HNil]]]]
[error] BigQueryParser[Sized[IndexedSeq[String], nat._3], String :: BigDecimal :: BigInt :: HNil].parse(s)
我发现调试此类问题的最佳方法是尝试手动构建您的实例。例如,这很好:
scala> BigQueryParser[Sized[IndexedSeq[String], _0], HNil]
res0: BigQueryParser[shapeless.Sized[IndexedSeq[String],shapeless.nat._0],shapeless.HNil] = BigQueryParser$$anon@2f4cd46d
但这会中断:
scala> deriveHCons[IndexedSeq[String], _0, String, HNil]
<console>:31: error: could not find implicit value for parameter conv: BigQueryParser[scala.collection.generic.IsTraversableLike[IndexedSeq[String]]#A,String]
deriveHCons[IndexedSeq[String], _0, String, HNil]
^
这表明 IsTraversableLike[Repr]#A
类型的投影出了问题。在这种情况下,我要做的第一件事就是将其设为类型参数(在本例中为 ReprA
),然后使用细化类型约束 IsTraversableLike[Repr]
实例:
implicit def deriveHCons[Repr, ReprA, L <: Nat, V, T <: HList](implicit
itl: IsTraversableLike[Repr] { type A = ReprA },
ev: AdditiveCollection[Repr],
ts: BigQueryParser[Sized[Repr, L], T],
conv: BigQueryParser[ReprA, V]
): BigQueryParser[Sized[Repr, Succ[L]], V :: T] =
new BigQueryParser[Sized[Repr, Succ[L]], V :: T] {
def parse(s: Sized[Repr, Succ[L]]): Try[V :: T] =
for {
h <- conv.parse(s.head)
t <- ts.parse(s.tail)
} yield h :: t
}
这很好用:
scala> println(
| BigQueryParser[
| Sized[IndexedSeq[String], nat._3],
| String :: BigDecimal :: BigInt :: HNil
| ].parse(s)
| )
Success(Testing :: 2.0 :: 1 :: HNil)
您可能还可以进行其他简化(例如,直接使用 _0
而不是 L <: _0
类型参数),但此修复至少应该让事情顺利进行。