Scala中的一行布尔模式匹配

时间:2015-05-26 23:44:05

标签: scala pattern-matching

有没有办法在Scala中以更优雅的方式编写此代码?

基本上我有以下代数数据类型:

function onFormSubmit(e) {

  // you need to add this line to add offline event object access auth
  // run once in script editor - you could delete it after if you want
  var f = FormApp.getActiveForm();

  // test for response and use static if none exists
  var responses = [
    "test data",
    "test data2",
    "test data3",
    "test data4",
    "test data5",
    "test data6",
    "test data7"
  ];

  responses = (e && e.response) ? 
    e.response.getItemResponses()
              .map(function (r) {
                return r.getResponse();
              }) : (e && e.values) ? e.values : responses;

  // snip //

  var jobsite = responses[2];
  var date_time = responses[3];
  var submit_name = responses[4];
  var weather = responses[5];
  var temp = responses[6];
  var super_name = responses[7];
  var job_num = responses[8]; 

  // snip //

}

我想检查给定变量是否与内部的特定术语匹配 条件表达式。例如,我可以写

trait Exp
case class Atom(i: Int) extends Exp
case class Add(l: Exp, r: Exp) extends Exp

然而,这是丑陋和冗长的。有更优雅的选择吗?

3 个答案:

答案 0 :(得分:4)

您可以使用PartialFunction及其isDefinedAt方法:

type MatchExp = PartialFunction[Exp, Unit]  // alias

val isOnePlusTwo: MatchExp = {
  case Add(Atom(1), Atom(2)) =>
}

if (isOnePlusTwo.isDefinedAt(x)) println("match")

match表达式会产生FunctionPartialFunction,具体取决于预期的类型。类型别名只是为了方便起见。

另一种可能性,如果你不需要通过模式匹配进行解构,那就是简单地依赖表达式的相等性:

if (x == Add(Atom(1), Atom(2))) println("match")

这是有效的,因为您使用case class es,它们具有正确的相等实现。

答案 1 :(得分:4)

使用这些来简洁:

scala> import PartialFunction._
import PartialFunction._

scala> condOpt(x) { case Add(Atom(x), Atom(y)) => x + y }
res2: Option[Int] = Some(3)

scala> cond(x) { case Add(Atom(x), Atom(y)) => println("yep"); true }
yep
res3: Boolean = true

scala> List(x, Atom(42)) flatMap (condOpt(_) { case Add(Atom(x), Atom(y)) => x + y })
res4: List[Int] = List(3)

答案 2 :(得分:2)

您可以将println放入match并完全摆脱if

x match {
  case Add(Atom(1), Atom(2)) => println("match")
  case _ => {} //do nothing
}