如何将元素附加到KList?

时间:2019-12-27 20:48:08

标签: scala generics types functional-programming shapeless

如何在保持KList原始类型的同时将元素附加到KList?我仍然不了解形状,真的不清楚从函数中期望什么类型。

下面是我正在尝试做的一个例子。我想使用类型约束来确保所有值都符合Box[_],但是我也尝试了使用普通HList的不受约束的示例,但仍然无法对其进行编译。

import shapeless._
import shapeless.UnaryTCConstraint.*->*

case class Box[T](value: T)

case class BoxBuilder[B <: HList](boxes: B) {
  def add[T](box: Box[T]): BoxBuilder[HList] = {
    this.copy(boxes = boxes :+ box)
  }
}

case class BoxBuilderTC[B <: HList : *->*[Box]#λ](boxes: B) {
  def add[T](box: Box[T]): BoxBuilder[HList] = {
    this.copy(boxes = boxes :+ box)
  }
}

在这里我可能缺少一些无形的基础知识,因此,其他任何提示/建议都将受到欢迎。

1 个答案:

答案 0 :(得分:3)

尝试添加必要的隐式参数/上下文边界

import shapeless._
import shapeless.UnaryTCConstraint.*->*
import shapeless.ops.hlist.Prepend

case class Box[T](value: T)

case class BoxBuilder[B <: HList](boxes: B) {
  def add[T](box: Box[T])(implicit prepend: Prepend[B, Box[T] :: HNil]): BoxBuilder[prepend.Out] = {
    this.copy(boxes = boxes :+ box)
  }
}

case class BoxBuilderTC[B <: HList : *->*[Box]#λ](boxes: B) {
  def add[T, Out <: HList : *->*[Box]#λ](box: Box[T])(implicit
                                        prepend: Prepend.Aux[B, Box[T] :: HNil, Out]
  ): BoxBuilderTC[Out] = {
    this.copy(boxes = boxes :+ box)
  }
}

通常只写HList而不是HList的特定子类型太困难了。