简体   繁体   English

从一类Hoid of Monoids中导出零的HList

[英]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类型,它返回NoneHList ,其中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 看起来HTTT可以由IsHCons提供

def createHList[L <: HList](implicit ihc: IsHCons[L]): HList = {
    type HT = ihc.H
    type TT = ihc.T
    //
}

But that rises two problems 但这引发了两个问题

  1. How to compare types? 如何比较类型?
  2. Compiler can not find 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM