我正在尝试以下课程
import shapeless._
import syntax.std.tuple._
class TestedClass[HL](nodes: HL) {
def addElement[T, OUT](clause: HL => T) = {
new TestedClass[OUT](nodes :+ clause(nodes))
}
}
显然这个片段没有编译。我不知道如何将新元组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)]
Scala可以吗?
答案 0 :(得分: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))))
}
}
然后:
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
每当您想要使用Shapeless操作时,基本技巧就是找到您需要的类型类,并将相应的实例作为隐式参数。在这种情况下,元组的Prepend
就是我们想要的。
答案 1 :(得分:0)
您可以将另一个HList附加到HList:
class TestedClass[A <: HList](nodes: A) {
def addElement[B, C](clause: A => B) = {
new TestedClass(nodes :: (clause(nodes) :: HNil))
}
// def split[H, T <: HList](l: H :: T) = (l.head, l.tail)
}