从一个类型的幺半群HList中获得零的HList [英] Deriving HList of zeroes from a type of HList of Monoids
问题描述
我正在学习不成形,目前我正在尝试创建一个执行以下操作的函数:
给定类型 HList
它返回> HList
无
s,其中选项
例如:
create [String :: Int :: HNil] //返回None [String] :: None [Int] :: HNil
所以逻辑如下:
def create [A< ;: HList] {
type HT = ??? //以某种方式获取头像类型
类型TT = ??? //以某种方式得到Tail type
//如果HT是HNil HNil else Option.empty [HT] :: create [TT]
}
看起来像 HT
和 TT
可以由 IsHCons
def createHList [L <:HList](隐式ihc :IsHCons [L]):HList = {
type HT = ihc.H
type TT = ihc.T
//
}
但是这会增加两个问题
- 如何比较类型?
- 编译器无法找到用于递归调用的
IsHCons [TT]
。 (如何从IsHCons [L]
获取ISHCons [TT]
?甚至不可能为!)
我认为我可以避开(1)对于 HNil
和非 HNil
,所以编译器会根据类型选择正确的隐式。
我正朝着正确的方向前进吗?
鉴于此,可能值得多提一些一般性问题。考虑到Monoid的 HList
,是否可以派生出零 HList
,其中包含给零单元的零?
谢谢!
HList
的Monoid 实例,其中每个元素类型都有它的 Monoid
实例: trait Monoid [T] {
def zero:T
def plus(t1:T,t2:T) :T
Monoid {
implicit val HNilMonoid:Monoid [HNil] = new Monoid [HNil] {
def zero = HNil
def (hn1:HNil,hn2:HNil)= HNil
}
隐含def HConsMonoid [H,T <:HList](隐式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)
}
}
(其实,我wo现在,假设我们有 Monoid,那么我们就可以自动地得到上述结果,但是我并不是无形中的专家)
Monoid [String]
,您可以: 隐式地[Monoid [Int :: String :: HNil]]。zero
正是你想要的,即 HList
为零。
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.
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 byIsHCons
def createHList[L <: HList](implicit ihc: IsHCons[L]): HList = {
type HT = ihc.H
type TT = ihc.T
//
}
But that rises two problems
- How to compare types?
- Compiler can not find
IsHCons[TT]
for recursive call. (How to getISHCons[TT]
fromIsHCons[L]
? It is not even possible forHNil
!)
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.
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?
Thanks!
It's fairly easy to define Monoid
instance for every HList
where each element type has its Monoid
instance:
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:
implicitly[Monoid[Int :: String :: HNil]].zero
which is exactly what you want, i.e. a HList
of zeros.
这篇关于从一个类型的幺半群HList中获得零的HList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!