首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala,将异构映射- Hmap与单类操作结合在一起

Scala,将异构映射- Hmap与单类操作结合在一起
EN

Stack Overflow用户
提问于 2018-07-09 15:22:46
回答 1查看 176关注 0票数 2

我希望创建一个包含任意数量定义的元组的异构映射:

代码语言:javascript
复制
A -> B
C -> D
E -> F
etc

现在每种类型的B,D,F。在理论上,我可以为我的异构地图创建一个Monoid。

是否有一个优雅的方法来实现这一点呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-10 13:32:57

那得看情况。如果您只想合并映射,那么很简单:只需HMap.empty[YourType](hm1.underlying ++ hm2.underlying)

但是你提到的单面表示你想要在相应的地方合并值。

我要说的是,没有补充资料是不可能的。例如,在编译时就可以知道这些信息,您在HMap中输入的类型的协积。

HMap不为您跟踪它,因此您必须自己实现它,或者使用一些包装器/构建器来更新每次添加内容时返回的类型。

代码语言:javascript
复制
class Wrapper[R[_,_], Vs <: Coproduct](hmap: HMap[R] = HMap.empty[R]) {

  def +[K,V](k: K, v: V): Wrapper[R, V :+: Vs] = new Wrapper(hmap + (k,v))
}

object Wrapper {

  def apply[R[_,_]]: Wrapper[R, CNil] = new Wrapper()
}

这个Coproduct将允许您构建一些更通用的单半群(我实现半群是为了简单起见):

代码语言:javascript
复制
// treat it as pseudocode, sth might not work here
trait CoproductSemigroup[A] { def combine(a1: Any, a2: Any): Any }
implicit val cnilCombine = new CoproductSemigroup[CNil] { def combine(a1: Any, a2: Any): Any = ??? }
implicit val coproductCombine[H : ClassTag : Semigroup,
                              T <: Coproduct : CoproductSemigroup] =
  new CoproductSemigroup[H :+: T] {

    def combine(a1: Any, a2: Any): Any = {
      if (implicitly[ClassTag[H].runtimeClass.isInstance(a1) && 
            implicitly[ClassTag[H].runtimeClass.isInstance(a2))
        implicitly[Semogroup[H].combine(a1.asInstanceOf[H], a2.asInstanceOf[H])]
      else
        implicitly[CoproductSemigroup[T]].combine(a1, a2)
    }
  }

这已经变得很难看了,然后您将不得不对每个组使用manually group values by the same key并应用这个函数。

最后,您必须从上面的代码中创建一个单样体。最有可能是包装器,因为它已经包含了您在这些实现中确实需要的类型信息。

也许有更好的方法来实现它,但我唯一能看到的是.又丑又不安全。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51248972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档