【发布时间】:2015-03-06 01:59:47
【问题描述】:
我正在尝试学习 Shapeless,并且我想定义一个将无形记录实例相加的幺半群。请注意,我使用的是 algebird monoids(不是 scalaz),但我确信它们非常相似。这是我想做的一个例子:
val result = Monoid.sum(
('a ->> 1) :: ('b ->> 1) :: HNil,
('a ->> 4) :: ('b ->> 3) :: HNil,
('a ->> 2) :: ('b ->> 6) :: HNil)
// result should be: ('a ->> 7) :: ('b ->> 10) :: HNil
我想出了如何为HList编写monoid实例,如下:
implicit val HNilGroup: Group[HNil] = new ConstantGroup[HNil](HNil)
implicit val HNilMonoid: Monoid[HNil] = HNilGroup
class HListMonoid[H, T <: HList](implicit hmon: Monoid[H], tmon: Monoid[T]) extends Monoid[::[H, T]] {
def zero = hmon.zero :: tmon.zero
def plus(a: ::[H, T], b: ::[H, T]) =
hmon.plus(a.head, b.head) :: tmon.plus(a.tail, b.tail)
}
implicit def hListMonoid[H, T <: HList](implicit hmon: Monoid[H], tmon: Monoid[T]) = new HListMonoid[H, T]
这让我可以写:
val result = Monoid.sum(
1 :: 1 :: HNil,
4 :: 3 :: HNil,
2 :: 6 :: HNil)
// result is 7 :: 10 :: HNil
现在我可以对 HList 实例求和,缺少的部分似乎是定义可以对 ('name ->> 1) 形式的字段求和的 monoid 实例,我的 IDE 告诉我它具有以下类型:Int with record.KeyTag[Symbol with tag.Tagged[Constant(name).type] { .. }, Int] { .. }。在这一点上我被卡住了,因为我只是不知道该怎么做。
【问题讨论】:
标签: scala record typeclass shapeless