在Scala中折叠类似的case语句

时间:2015-06-14 23:37:55

标签: scala functional-programming pattern-matching

使用一个case语句,是否有一种优雅的方式来执行类似下面的示例?

foobar match {
    case Node(Leaf(key, value), parent, qux) => {
        // Do something with parent & qux
    }
    case Node(parent, Leaf(key, value), qux) => {
        // Do something with parent & qux (code is the same as in the previous case)
    }
    // other cases
}

为了理解这里发生了什么:foobar是二叉树的节点,当节点的一个祖先是Leaf节点时,我匹配这些情况。这些是使用的类:

abstract class Tree
case class Node(left: Tree, right: Tree, critBit: Int) extends Tree
case class Leaf(key: String, value:String) extends Tree

1 个答案:

答案 0 :(得分:4)

您可以使用自定义提取器将匹配部分从逻辑部分抽象出来:

object Leafed {
  def unapply(tree: Tree) = tree match {
    case Node(Leaf(_, _), parent, qux) => Some((parent, qux))
    case Node(parent, Leaf(_, _), qux) => Some((parent, qux))
    case _ => None
  }
}

然后你可以定义这样的方法:

def doSomething(tree: Tree): Int = tree match {
  case Leafed(parent, qux) => qux
  case _ => -100
}

您可以这样使用:

scala> val leaf = Leaf("foo", "bar")
leaf: Leaf = Leaf(foo,bar)

scala> doSomething(leaf)
res7: Int = -100

scala> doSomething(Node(leaf, Node(leaf, leaf, 5), 10))
res8: Int = 10

scala> doSomething(Node(Node(leaf, leaf, 5), leaf, 10))
res9: Int = 10

否则你运气不好 - 正如Marth在上面指出的那样,模式替代方案对你没有帮助。