首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由一类单子元的HList导出零的HList

由一类单子元的HList导出零的HList
EN

Stack Overflow用户
提问于 2016-05-21 13:05:39
回答 1查看 90关注 0票数 3

我正在学习无形状的知识,目前我正在尝试创建一个函数来执行以下操作:给定一个HList类型,它返回HList of Nones,而Option类型对应于给定的HList类型。

例如:

代码语言:javascript
复制
create[String :: Int :: HNil] // returns None[String] :: None[Int] :: HNil

因此,逻辑如下:

代码语言:javascript
复制
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] 
}

看起来HTTT可以由IsHCons提供

代码语言:javascript
复制
def createHList[L <: HList](implicit ihc: IsHCons[L]): HList = {
    type HT = ihc.H
    type TT = ihc.T
    //
}

但这就产生了两个问题

  1. 如何比较类型?
  2. 编译器无法找到用于递归调用的IsHCons[TT]。(如何从ISHCons[TT]获得IsHCons[L]HNil是不可能的!)

我认为我可以通过为HNil和非HNil提供内嵌来绕过(1),因此编译器将根据类型选择正确的隐式。

我朝正确的方向走去了吗?

既然如此,也许值得提出更一般性的问题。给定幺半群的HList,是否有可能导出由给定幺半群的零点组成的零HList

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-21 13:35:06

在每个元素类型都有其Monoid实例的情况下,很容易为每个HList定义Monoid实例:

代码语言:javascript
复制
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)
    }
}

(实际上,我希望“无形”能够自动导出上述内容,但我不是“无型”方面的专家。)

现在,假设我们在其他地方定义了Monoid[Int]Monoid[String],您只需:

代码语言:javascript
复制
implicitly[Monoid[Int :: String :: HNil]].zero

这正是你想要的,也就是零的HList

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

https://stackoverflow.com/questions/37363337

复制
相关文章

相似问题

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