我目前看起来像这样:
data foreach {
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(a))))))))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a))))))))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a)))))))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a))))))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a)))))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a))))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a)))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a))))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a)))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a))))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(a)))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Left(Right(a))))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Left(Right(a)))))))) => /* Do something */
case Left(Left(Left(Left(Left(Left(Right(a))))))) => /* Do something */
case Left(Left(Left(Left(Left(Right(a)))))) => /* Do something */
case Left(Left(Left(Left(Right(a))))) => /* Do something */
case Left(Left(Left(Right(a)))) => /* Do something */
case Left(Left(Right(a))) => /* Do something */
case Left(Right(a)) => /* Do something */
case Right(a) => /* Do something */
}
我想知道是否有任何方法可以实现某种递归功能,使我的模式匹配更清晰。看起来更像是这样的东西:
data foreach {
case Foo(a, 3) => /* Do something */
case Foo(a, 2) => /* Do something */
case Foo(a, 1) => /* Do something */
case Foo(a, 0) => /* Do something */
}
答案 0 :(得分:1)
我就是这样做的。
object Test extends App {
object Foo {
def unapply[T: Manifest](e: Either[_, T]): Option[(T, Int)] = e match {
case Right(rVal: T) => Some(Tuple2(rVal, 0))
case Left(left: Either[_, T]) => left match {
case Foo(rVal: T, d) => Some(Tuple2(rVal, d + 1))
case _ => None
}
case _ => None
}
def apply[T, E <: Either[E, T]](t: T, d: Int): Either[E, T] = {
Either.cond[E, T](d == 0, t, apply(t, d - 1).asInstanceOf[E])
}
}
val data = List(
Foo("a", 0),
Foo("b", 2),
Foo("c", 3),
Foo("d", 10),
Left(10)
)
data foreach println
println()
data collect {
case Foo(a, 0) => println(s"$a at 0")
case Foo(a, d) => println(s"Generic: $a at $d")
}
}
此测试应用有此输出:
// Right(a)
// Left(Left(Right(b)))
// Left(Left(Left(Right(c))))
// Left(Left(Left(Left(Left(Left(Left(Left(Left(Left(Right(d)))))))))))
// Left(10)
//
// a at 0
// Generic: b at 2
// Generic: c at 3
// Generic: d at 10