包含案例类的列表中的模式匹配

时间:2012-04-12 02:56:25

标签: list scala pattern-matching

this topic的序列中,我正在研究一个允许将块组成scala的系统,这样我就可以使用模式匹配来创建重写规则系统。

但是我被卡住了。

我有这个课程:

abstract class Block(n: String, in: List[Input], out: List[Out]){
  def name = n; def outputs = out; def inputs = in
}
case class GroupBlock(n: String, blocks: List[Block], in: List[Input], 
                      out: List[Out]) extends Block(n, in, out)
case class StandardBlock(n: String, in: List[Input], out: List[Out])
           extends Block(n, in, out)

abstract class Point(n: String){ def name = n }
case class Input(n:String) extends Point(n)

abstract class Out(n: String) extends Point(n)
case class Output(n:String) extends Out(n) 
case class Connection(connectedInput: Input, n: String) extends Out(n)

现在想象一下,我有这个没有显示的例子:

enter image description here

映射到此:

val inputA = Input("sumA")
val inputB = Input("sumB")
val outputB = Output("B")

val sumAB =
    GroupBlock("GroupedSum",
      StandardBlock("Sum", List(inputA, inputB), List(outputB)) :: 
      StandardBlock("Input Provider", null, Connection(inputA, "A")::Nil ) ::
      StandardBlock("Input Provider", null, Connection(inputB, "B")::Nil ) ::         
      Nil, 
      null, 
      List(outputB))

所以...我希望能够说:如果2 "Integer providers""Sum"有关,那么......

我设法通过模式匹配识别出存在的“输入提供者”:

sumAB match{
    case GroupBlock(_, 
          StandardBlock("Input Provider", null, _ :: Connection(input, _) :: _ ) :: _,
           _, _)
        => ...
    case GroupBlock(_,
          StandardBlock("Input Provider", null, Connection(input, _) :: _ ) :: _, 
          _, _)
        => ...
    //Covering 2 more cases where the order on the list matters
}

如何说“在列表中找到名称为StandardBlock的{​​{1}}的案例”?因为这是我的主要问题之一。我需要指定所有可能的组合......现在我想做类似

的事情
"Input Provider"

但这意味着“找到一个案例,其中”输入提供者“位于列表的开头,而Sum块跟随”Sum“”。我希望:“找到一个存在”输入提供者“的案例与”和“存在于同一列表中。

列表中的这种“查询”也可用于检查输入提供程序是否与找到它的Sum块连接。我可以使用该变量case GroupBlock(_, StandardBlock("Input Provider", null, Connection(input, _) :: StandardBlock("Sum", inputList, _ ) :: _, _, _) 并询问input在inputList中的情况。

1 个答案:

答案 0 :(得分:3)

您可以在匹配条款中使用警卫来提供帮助。他们是这样的:

case 模式 if 后卫 =>

其中guard是一个表达式,可以使用已绑定在模式中的变量。所以我认为可能做你想做的事情:

sumAB match {
  case GroupBlock(groupBlockName, blocks, _, _) if blocks.exists {
    case StandardBlock("Input Provider", _, inputProv_out) => blocks.exists { 
      case StandardBlock("Sum", sum_in, _) =>
        sum_in.exists { input =>
          inputProv_out.collect{ case Connection(connectedInput,_) =>
            connectedInput}.contains(input)
        }
      case _ =>
        false 
    }
    case _ => false
  } =>
    println("found")
  case _ =>
    println("no match")
}

这是尝试翻译您正在编写的内容查找存在输入提供程序的组块,其中inputProv_out输出之一连接到总和sum_in输入之一

话虽如此,如果我没有犯错,我会感到惊讶。这表明您的数据结构可能不是您想要做的最好的。或者您可能需要帮助函数才能表达某些属性。