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)