如何将元素追加到HList

Bar*_*icz 4 scala shapeless

我正在尝试下面的课程

import shapeless._
import syntax.std.tuple._

class TestedClass[HL](nodes: HL) {

    def addElement[T, OUT](clause: HL => T) = {
        new TestedClass[OUT](nodes :+ clause(nodes))
    }
}
Run Code Online (Sandbox Code Playgroud)

显然这个片段没有编译.我不知道如何将新的元组nodes :+ clause(nodes)类型绑定到OUT.我想要实现的目标如下:

scala> val step1 = new TestedClass[(Int)](1)
res1: TestedClass[(Int)]

scala> val step2 = step1.addElement(nodes => 2.0)
res1: TestedClass[(Int, Double)]
Run Code Online (Sandbox Code Playgroud)

Scala有可能吗?

Tra*_*own 6

是的,它可能,虽然不太好,因为Scala不提供语法Tuple1.但以下内容将起作用:

import shapeless._, ops.tuple.Prepend

class TestedClass[HL](nodes: HL) {
  def addElement[T, OUT](clause: HL => T)
    (implicit prepend: Prepend.Aux[HL, Tuple1[T], OUT]) = {
      new TestedClass[OUT](prepend(nodes, Tuple1(clause(nodes))))
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

scala> val step1 = new TestedClass[Tuple1[Int]](Tuple1(1))
step1: TestedClass[(Int,)] = TestedClass@4fb78b02

scala> val step2 = step1.addElement(nodes => 2.0)
step2: TestedClass[(Int, Double)] = TestedClass@20406333
Run Code Online (Sandbox Code Playgroud)

想要使用Shapeless操作时的基本技巧是找到所需的类型类,并将相应的实例作为隐式参数.在这种情况下,Prependfor元组是我们想要的.