我有以下课程;
trait Part
case class Part1() extends Part
case class Part2() extends Part
case class Part3(part1: Part1, part2: Part2) extends Part
case class Part4(part1: Part1, part2: Option[Part2], part3: List[Part3]) extends Part
case class Part5(name: String, part4: Part4) extends Part
我将Part1
和归类Part2
为简单的部分和,Part3
以及Part4
“组合部分”,因为它们仅由其他部分或其他部分的某些效果组成。
我希望能够将分组的部件转换为部件列表,反之亦然。但我只想使用两种方法来做到这一点。一个用于分组部分到列表,一个用于列表到分组部分,因为我有数百个扩展类,Part
我不想为所有这些类编写方法。
我设法将分组部分转换为列表如下;
type IsParts[x] <: Boolean = x match {
case Part => true
case List[Part] => true
case Option[Part] => true
case _ => false
}
def getParts[T <: Product](p: T)
(using
mirror: Mirror.ProductOf[T],
ev: Tuple.Filter[mirror.MirroredElemTypes, IsParts] =:= mirror.MirroredElemTypes) : List[Part] = {
p.productIterator.toList.flatMap{e => e match {
case p: Part => List(p)
case ps: List[Part] => ps
case op: Option[Part] => op.map(p => List(p)).getOrElse(List())
}}.asInstanceOf[List[Part]]
}
它按预期工作
val p1 = Part1()
val p2 = Part2()
val p3 = Part3(p1, p2)
val p4 = Part4(p1, None, List(p3))
val p5 = Part5("part 5", p4)
@main def hello: Unit =
println(s"Part1 : ${getParts(p1)}") // Part1 : List()
println(s"Part2 : ${getParts(p2)}") // Part2 : List()
println(s"Part3 : ${getParts(p3)}") // Part3 : List(Part1(), Part2())
println(s"Part4 : ${getParts(p4)}") // Part4 : List(Part1(), Part3(Part1(),Part2()))
// getParts(p5) // does not compile as expected.
如何将零件列表转换为分组零件?(忽略从部件列表到分组部件的函数是部分的事实。)
Codewise 我要求实现类似的东西:
def toGroupedPart[T <: Part](parts: List[Part])
(using
mirror: Mirror.ProductOf[T],
ev: Tuple.Filter[mirror.MirroredElemTypes, IsParts] =:= mirror.MirroredElemTypes): T = ???
我会像这样使用它;
toGroupedPart[Part4](myPartList) // returns Part4
// toGroupedPart[Part5](myPartList) // does not compile because Part5 is not a grouped part.
Scastie为工作部分。