Scala 到分区后的通用HList上的[List]
所以我试着这样做:Scala 到分区后的通用HList上的[List],scala,shapeless,Scala,Shapeless,所以我试着这样做: @ import shapeless._ import shapeless._ @ case class A(); case class B(); case class C() defined class A defined class B defined class C case class Stuff(a: List[A], b: B, c: List[C]) @ def stuffs[H <: HList](hl:H)( implicit pb:Part
@ import shapeless._
import shapeless._
@ case class A(); case class B(); case class C()
defined class A
defined class B
defined class C
case class Stuff(a: List[A], b: B, c: List[C])
@ def stuffs[H <: HList](hl:H)(
implicit
pb:Partition[H,B],
pa:Partition[H,List[A]],
pc:Partition[H,List[C]],
tl: ToTraversable[H, List]
):List[Stuff] =
hl.filter[B].to[List].map {
b =>
Stuff(
a = hl.filter[List[A]].to[List].flatten,
b = b,
c = hl.filter[List[C]].to[List]flatten
)
}
Compilation Failed
Main.scala:374: could not find implicit value for parameter ts: shapeless.ops.hlist.ToTraversable[pb.Prefix,List]
hl.filter[B].to[List].map {
^
Main.scala:377: could not find implicit value for parameter ts: shapeless.ops.hlist.ToTraversable[pa.Prefix,List]
a = hl.filter[List[A]].to[List].flatten,
但事实并非如此,这是有道理的(它允许定义函数,但在尝试使用时失败,这仍然很奇怪):
@def stuffs[H如果您需要使用不成形校样的输出类型,您可以使用校样对应的Aux
类型以及附加的类型参数,在同一参数列表中获取该输出类型的校样:
def stuffs[H <: HList, Prefix <: HList, Suffix <: HList](implicit
pb: Partition.Aux[H, B, Prefix, Suffix],
traversablePrefix: ToTraversable[Prefix, List]
....
)
def stuffs[H您上次的尝试非常接近。@Jeremy说得对,分区
操作的输出类型需要类型变量。您还需要指定ToTraversable
操作的输出类型,以确定转换结果的元素类型
import shapeless._
import ops.hlist._, ops.traversable._
case class A()
case class B()
case class C()
case class Stuff(a: List[A], b: B, c: List[C])
def stuffs[H <: HList, PA <: HList, SA <: HList, PB <: HList, SB <: HList, PC <: HList, SC <: HList](hl:H)
(implicit
pa: Partition.Aux[H, List[A], PA, SA],
pb: Partition.Aux[H, B, PB, SB],
pc: Partition.Aux[H, List[C], PC, SC],
prefixToTraversableA: ToTraversable.Aux[PA, List, List[A]],
prefixToTraversableB: ToTraversable.Aux[PB, List, B],
prefixToTraversableC: ToTraversable.Aux[PC, List, List[C]]
): List[Stuff] = {
val as: List[A] = hl.filter[List[A]].to[List].flatten
val bs: List[B] = hl.filter[B].to[List]
val cs: List[C] = hl.filter[List[C]].to[List].flatten
bs.map(Stuff(as, _, cs))
}
val hl = List(A(), A()) :: B() :: List(C()) :: B() :: List(C(), C()) ::HNil
val ss = stuffs(hl)
val expected =
List(
Stuff(List(A(), A()), B(), List(C(), C(), C())),
Stuff(List(A(), A()), B(), List(C(), C(), C()))
)
assert(ss == expected)
导入无形状_
导入ops.hlist.\ ops.traversable_
案件类别A()
案件B类()
案件类别C()
案例类材料(a:List[a],b:b,c:List[c])
很好,我想我现在终于理解了Aux。我得说,就像到目前为止所有的shapeless一样,一旦理解了,原理就很简单了。
@ def stuffs[H <: HList, PA <: HList, SA <: HList, PB <: HList, SB <: HList] (hl:H)(
implicit
pa:Partition.Aux[H,List[A],PA, SA ],
pb:Partition.Aux[H,B,PB, SB ],
prefixToTraversableA: ToTraversable[SA, List],
prefixToTraversableB: ToTraversable[SB, List]
) = (hl.filter[List[A]].to[List], hl.filter[B].to[List])
Compilation Failed
Main.scala:380: could not find implicit value for parameter ts: shapeless.ops.hlist.ToTraversable[pa.Prefix,List]
) = (hl.filter[List[A]].to[List], hl.filter[B].to[List])
^
Main.scala:380: could not find implicit value for parameter ts: shapeless.ops.hlist.ToTraversable[pb.Prefix,List]
) = (hl.filter[List[A]].to[List], hl.filter[B].to[List])
^
def stuffs[H <: HList, Prefix <: HList, Suffix <: HList](implicit
pb: Partition.Aux[H, B, Prefix, Suffix],
traversablePrefix: ToTraversable[Prefix, List]
....
)
import shapeless._
import ops.hlist._, ops.traversable._
case class A()
case class B()
case class C()
case class Stuff(a: List[A], b: B, c: List[C])
def stuffs[H <: HList, PA <: HList, SA <: HList, PB <: HList, SB <: HList, PC <: HList, SC <: HList](hl:H)
(implicit
pa: Partition.Aux[H, List[A], PA, SA],
pb: Partition.Aux[H, B, PB, SB],
pc: Partition.Aux[H, List[C], PC, SC],
prefixToTraversableA: ToTraversable.Aux[PA, List, List[A]],
prefixToTraversableB: ToTraversable.Aux[PB, List, B],
prefixToTraversableC: ToTraversable.Aux[PC, List, List[C]]
): List[Stuff] = {
val as: List[A] = hl.filter[List[A]].to[List].flatten
val bs: List[B] = hl.filter[B].to[List]
val cs: List[C] = hl.filter[List[C]].to[List].flatten
bs.map(Stuff(as, _, cs))
}
val hl = List(A(), A()) :: B() :: List(C()) :: B() :: List(C(), C()) ::HNil
val ss = stuffs(hl)
val expected =
List(
Stuff(List(A(), A()), B(), List(C(), C(), C())),
Stuff(List(A(), A()), B(), List(C(), C(), C()))
)
assert(ss == expected)