0

我目前有一些看起来像这样的东西:

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 */
        }
4

1 回答 1

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
于 2014-10-24T17:52:30.053 回答