我对scala相当新,我想解析一个案例类列表:
abstract class D
case class D0(a: Int, b: Int) extends D
case class D2(c: String, d: Int) extends D
case class D3(e: Int, f: String) extends D
case class D4(e: String, f: String, g: Int) extends D
我想解析List [D]的一个实例。 列表中有一个特殊的顺序,可以用类似BNF的表示法来解释:
rep(D0 -> D4 -> rep(D2 -> opt(rep(d3))))
D0之后是D4,然后是1-n D2,每个D2后跟1-n D3等等......
我想创建一个类型列表:
type T0 = (D0, D4, List[(D2, List[D3])])
到目前为止,我发现的所有解决方案都是丑陋且有状态的。 经验丰富的scala开发人员将如何实现这一目标?
谢谢
答案 0 :(得分:4)
对我来说这看起来并不太丑(假设我正确理解了这个问题,这通常不称为解析):
type T1 = (D2, List[D3])
// MatchError if the list doesn't look the way you expected
def matchList(l: List[D]): List[T0] = l match {
case (d0: D0) :: (d4: D4) :: tail =>
val (d2d3s, tail1) = matchD2D3s(tail)
(d0, d4, d2d3s) :: matchList(tail1)
case Nil => Nil
}
def matchD2D3s(l: List[D]): (List[T1], List[D]) = l match {
case (d2: D2) :: tail =>
val (d3s, tail1) = tail.span(_.isInstanceOf[D3])
val (otherD2D3s, tail2) = matchD2D3s(tail1)
((d2, d3s) :: otherD2D3s, tail2)
case l => (Nil, l) // no d2s
}