查找 Shapeless HList 的类型类实例 [英] Find type class instances for Shapeless HList
问题描述
说我有一个特征 Show[T]
,比如 Scalaz 中的特征:https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Show.scala#L9
Say that I have a trait Show[T]
such as the one in Scalaz: https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Show.scala#L9
我还有一个 Shapeless HList
,它看起来像 "1" :: 2 :: 3L :: HNil
.
I also have a Shapeless HList
that may look like "1" :: 2 :: 3L :: HNil
.
有没有办法找到每个元素的 Show
实例并应用 shows
这样我最终得到 "1" :: "2" :: "3L" :: HNil
?
Is there a way to find the Show
instance for each element and apply shows
such that I end up with "1" :: "2" :: "3L" :: HNil
?
如果任何元素属于在范围内没有隐式 Show
实例的类型,我会想要一个编译错误.
If any element were of a type that did not have an implicit Show
instance in scope I would want a compile error.
我认为,如果我建立一个 Show
实例的 HList
,我应该能够使用 zipApply
来获取 HList
我想要,但我不知道是否有办法让 Scala 推断 Show
实例的 HList
而不是我通过手.
I think that if I build up an HList
of the Show
instances I should be able to use zipApply
to get the HList
I want, but I don't know if there is a way to get have Scala infer the HList
of Show
instances instead of me building it up by hand.
推荐答案
如果您的目标是应用 Show
实例并且您不关心构建 HList代码>,最简单的方法可能是使用多态函数:
If your goal is to apply the Show
instances and you don't otherwise care about building up an HList
of them, the easiest approach is probably to use a polymorphic function:
import scalaz._, Scalaz._, shapeless._
val xs = "1" :: 2 :: 3L :: HNil
object show extends Poly1 {
implicit def forShowable[A: Show] = at[A](_.shows)
}
val strings: String :: String :: String :: HNil = xs map show
您可以通过稍微更改 Poly1
来获得实例的 HList
:
You could get an HList
of the instances by changing the Poly1
a bit:
object showInstance extends Poly1 {
implicit def forShowable[A: Show] = at[A](_ => Show[A])
}
在某些情况下,定义您自己的类型类以收集您拥有特定类型类实例的证据会很有用:
In some cases it can be useful to define your own type class to collect evidence that you've got certain type class instances:
trait AllShowable[L <: HList, S <: HList] {
def instances: S
}
implicit object hnilAllShowable extends AllShowable[HNil, HNil] {
def instances = HNil
}
implicit def hlistAllShowable[H: Show, TL <: HList, TS <: HList](
implicit ts: AllShowable[TL, TS]
) = new AllShowable[H :: TL, Show[H] :: TS] {
def instances = Show[H] :: ts.instances
}
但通常使用需要实例的多态函数映射会工作得很好.
But usually mapping with a polymorphic function that requires the instances will work just fine.
这篇关于查找 Shapeless HList 的类型类实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!