2012-04-12 4 views
1

In der Sequenz von this topic bin ich ein System changing, das Blöcke zu Scala komponieren kann, damit ich Mustervergleich verwenden kann, um ein Rewrite-Regel-System zu erstellen.Mustererkennung in Listen, die Fallklassen enthalten

Allerdings bin ich fest.

Ich habe diese Klassen:

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) 

Jetzt Stellen Sie sich vor, dass ich dieses Beispiel ohne Display:

enter image description here

in diese Mapped:

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)) 

So .. Ich möchte sagen können: Im Fall 2 "Integer providers" sind verbunden mit "Sum" dann ...

ich es geschafft, zu identifizieren, mit Pattern-Matching, als ein „Input Provider“ existiert mit diesem:

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 
} 

Wie kann ich „Finde mich einen Fall sagen, dass ein StandardBlock hat das hat den Namen "Input Provider" in der Liste "? Weil das eines meiner Hauptprobleme ist. Ich brauche alle möglichen Kombinationen geben ... Nun wollte ich so etwas wie

case GroupBlock(_, 
      StandardBlock("Input Provider", null, Connection(input, _) :: 
      StandardBlock("Sum", inputList, _ ) :: _, 
      _, _) 

tun, aber das bedeutet „Finde mir einen Fall, in dem ein‚Input Provider‘am Anfang der Liste ist und ein Sum Block folgt das "Sum" ". Und ich will: "Finde mich einen Fall, wo existiert ein" Input Provider "existiert in der gleichen Liste als" Sum ".

Diese Art von" Abfragen "in einer Liste sind auch nützlich, um zu überprüfen, ob der Input-Provider ist ... verbunden mit dem Sum Block, dass es gefunden wurde ich, dass variable input und fragen Sie nach Fällen verwenden können, wo input in Inputlist ist

+0

Verwandte Frage: http: // stackoverflow.com/questions/9891638/sollte-ich-ändern-zu-scala-zu-erstellen-ein-system-mit-rewrite-rules/9895047 (ja, ich weiß, es ist deins - es könnte helfen, die Leute verstehen, was Sie wollen) –

+0

Deshalb habe ich mit "In der Folge dieses Themas" mit einem Link dazu angefangen :) –

+0

Sorry, das habe ich verpasst. –

Antwort

3

Sie Wachen in Ihrem Spiel Klauseln verwenden können, um Sie gehen wie folgt aus:

caseMusterifSchutz=>

wobei guard ein Ausdruck ist, der die Variablen verwenden kann, die im Muster gebunden wurden. Also ich denke, das Macht tun, was Sie wollen:

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") 
} 

Dies ist ein Versuch, wie übersetzen, was Sie schreiben einen Gruppenblock finden, wo ein Eingangs Anbieter liegt vor, wenn eine seiner inputProv_out Ausgang einem der verbunden ist, die Summe sum_in Eingaben.

Mit diesem gesagt würde ich überrascht sein, wenn ich keinen Fehler machte. Das deutet darauf hin, dass Ihre Datenstruktur möglicherweise nicht das Beste für das ist, was Sie versuchen zu tun. Oder Sie benötigen Hilfsfunktionen, um bestimmte Eigenschaften auszudrücken.

+0

Es ist eine wirklich verwirrte Lösung. Und mein Beispiel war wahrscheinlich eines der einfachsten, die ich finden konnte. Sollte ich Case-Klassen vergessen und versuchen, mit der Unapply-Methode im Mustervergleich zu trainieren? Können Sie Änderungen in meiner Struktur vorschlagen, die das vereinfachen, was ich möchte? –

+0

@TiagoAlmeida, Ihr Diagramm mit Integer Provider, Summe und Anzeige scheint viel einfacher als Ihre tatsächlichen Strukturen. Könnten Sie die Fallklassen mehr wie Ihr Diagramm vereinfachen? – huynhjl

+0

Ich sehe keine Lösung dafür. Zuerst brauche ich einen Namen für jeden Block/Eingang/Ausgang, damit ich es dem Benutzer zeigen kann. Und zweitens muss ich die Verbindungen kennen. Obwohl ich für jede Art von Block eine Fallklasse erstellen kann (Ganzzahlanbieter ist eine Fallklasse, Summe ist eine Fallklasse) Ich glaube, das wird nicht revoluzionär sein ... Ich möchte meine Struktur vereinfachen, aber ich sehe nicht, wie ich es kann TU es. –