Scala 从一类幺半群的HList求零的HList

Scala 从一类幺半群的HList求零的HList,scala,functional-programming,shapeless,Scala,Functional Programming,Shapeless,我正在学习shapeless,目前我正在尝试创建一个函数,该函数可以执行以下操作: 给定一个HList类型,它返回Nones的HList,其中选项类型对应于给定的HList类型 例如: create[String :: Int :: HNil] // returns None[String] :: None[Int] :: HNil trait Monoid[T] { def zero: T def plus(t1: T, t2: T): T } object Monoid {

我正在学习shapeless,目前我正在尝试创建一个函数,该函数可以执行以下操作: 给定一个
HList
类型,它返回
None
s的
HList
,其中
选项
类型对应于给定的
HList
类型

例如:

create[String :: Int :: HNil] // returns None[String] :: None[Int] :: HNil
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)
    }
}
因此,逻辑如下:

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] 
}
但这带来了两个问题

  • 如何比较类型
  • 编译器找不到递归调用的
    IsHCons[TT]
    。(如何从
    ISHCons[L]
    获取
    ISHCons[TT]
    ?对于
    HNil
    !)
  • 我认为我可以绕过(1),为
    HNil
    和非
    HNil
    提供隐式,因此编译器将根据类型选择正确的隐式

    我是否朝着正确的方向前进

    考虑到这一点,或许值得提出更一般的问题。给定幺半群的
    HList
    ,是否可能导出由给定幺半群的零组成的零
    HList


    谢谢

    很容易为每个
    HList
    定义
    Monoid
    实例,其中每个元素类型都有其
    Monoid
    实例:

    create[String :: Int :: HNil] // returns None[String] :: None[Int] :: HNil
    
    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)
        }
    }
    
    这正是您想要的,即一个0的
    HList

    还有一个类似的派生
    Monoid