[英]Deriving HList of zeroes from a type of HList of Monoids
I am learning shapeless, and currently I am trying to create a function that does the following: given a type of an HList
it returns the HList
of None
s, with the Option
types corresponding to given HList
type. 我正在学习无形,目前我正在尝试创建一个执行以下操作的函数:给定一个HList
类型,它返回None
的HList
,其中Option
类型对应于给定的HList
类型。
For instance: 例如:
create[String :: Int :: HNil] // returns None[String] :: None[Int] :: HNil
So the logic is the following: 所以逻辑如下:
def create[A <: HList] {
type HT = ??? //somehow getting Head type
type TT = ??? //somehow getting Tail type
// if HT is HNil HNil else Option.empty[HT] :: create[TT]
}
Looks like the HT
and TT
can be provided by IsHCons
看起来HT
和TT
可以由IsHCons
提供
def createHList[L <: HList](implicit ihc: IsHCons[L]): HList = {
type HT = ihc.H
type TT = ihc.T
//
}
But that rises two problems 但这引发了两个问题
IsHCons[TT]
for recursive call. 编译器无法找到IsHCons[TT]
进行递归调用。 (How to get ISHCons[TT]
from IsHCons[L]
? It is not even possible for HNil
!) (如何从IsHCons[L]
获得ISHCons[TT]
? HNil
甚至不可能!) I think that I can get around the (1), by providing implicits for HNil
and non HNil
, so the compiler will pick up the right implicit, depending on the type. 我认为我可以绕过(1),通过为HNil
和非HNil
提供隐含,因此编译器会根据类型选择正确的隐式。
Am I moving towards the right direction? 我正朝着正确的方向前进吗?
Given that, may be it is worth to ask more general question. 鉴于此,可能值得提出更一般的问题。 Given the HList
of Monoids, is it possible to derive zero HList
, consisting of zeros of give monoids? 给定幺半群的HList
,是否有可能导出零HList
,由给出幺半群的零组成?
Thanks! 谢谢!
It's fairly easy to define Monoid
instance for every HList
where each element type has its Monoid
instance: 为每个HList
定义Monoid
实例相当容易,其中每个元素类型都有Monoid
实例:
trait Monoid[T] {
def zero: T
def plus(t1: T, t2: T): T
}
object Monoid {
implicit val HNilMonoid: Monoid[HNil] = new Monoid[HNil] {
def zero = HNil
def plus(hn1: HNil, hn2: HNil) = HNil
}
implicit def HConsMonoid[H, T <: HList](implicit hm: Monoid[H], tm: Monoid[T]): Monoid[H :: T] =
new Monoid[H :: T] {
def zero = hm.zero :: tm.zero
def plus(ht1: H :: T, ht2: H :: T) =
hm.plus(ht1.head, ht2.head) :: tm.plus(ht1.tail, ht2.tail)
}
}
(actually, I would expect shapeless to be able to derive the above automatically, but I'm not an expert on shapeless) (实际上,我希望无形能够自动导出上述内容,但我不是无形的专家)
Now, assuming that we have Monoid[Int]
and Monoid[String]
defined elsewhere, you can just: 现在,假设我们在其他地方定义了Monoid[Int]
和Monoid[String]
,您可以:
implicitly[Monoid[Int :: String :: HNil]].zero
which is exactly what you want, ie a HList
of zeros. 这正是你想要的,即零的HList
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.