2012-08-11 6 views
7

Ist es möglich, Schutzbedingungen mit Musterabgleich in versiegelten Fallklassendeklarationen zu kombinieren?Scala: Können Schutzbedingungen mit Musterabgleichen innerhalb der versiegelten Fallklassen-Deklarationen kombiniert werden

Ich realisiere, dass es möglich ist, Schutzbedingungen innerhalb des Matchblocks einzubeziehen, aber ich denke, dass es vorteilhaft wäre, diese Bedingungen in den versiegelten Fallklassen zu definieren. Dies würde Entwicklern erlauben, eine strenge Menge möglicher Eingaben zu definieren, die der Compiler beim Mustervergleich überprüfen würde.

Also zusammenfassend würde Ich mag das Äquivalent von so etwas wie dies in der Lage sein zu tun:

// create a set of pattern matchable cases with guards built in 

sealed abstract class Args 
case class ValidArgs1(arg1:Int,arg2:Int) if arg1>1 && arg2<10 extends Args 
case class ValidArgs2(arg1:Int,arg2:Int) if arg1>5 && arg2<6 extends Args 
case class InvalidArgs(arg1:Int,arg2:Int) if arg1<=1 && arg2>=10 extends Args 


// the aim of this is to achieve pattern matching against an exhaustive set of 
// pre-defined possibilities 

def process(args:Args){ 
    args match 
    { 
     case ValidArgs1 = > // do this 
     case ValidArgs2= > // do this 
     case InvalidArgs = > // do this 
    } 
} 

Antwort

-1

Ich glaube nicht, dass Sie allgemeine Einschränkungen/Behauptungen zu haben, werden in der Lage, die bei geprüft Kompilierzeit in Scala, weil Scala keine static verifier hat, die dazu benötigt würde. Wenn Sie interessiert sind, werfen Sie einen Blick auf (Forschungs-) Sprachen/Werkzeuge wie ESC/Java, Spec#, Dafny oder VeriFast.

Es kann Möglichkeiten geben, eine sehr begrenzte Anzahl von statischen Überprüfung mit dem regulären Compiler Scala mit type-level programming oder Scala macros zu haben, aber das ist nur eine wilde Vermutung von mir, da ich mit keinem von ihnen vertraut bin. Um ehrlich zu sein, muss ich zugeben, dass ich sehr überrascht wäre, wenn Makros hier wirklich helfen könnten.

Was funktioniert, Laufzeitprüfung, z.

case class Foo(arg1: Int, arg2: Int) { 
    require(arg1 < arg2, "The first argument must be strictly less than " + 
         "the second argument.") 
} 

Foo(0, 0) 
    /* java.lang.IllegalArgumentException: requirement failed: 
    *  The first argument must be strictly less than the second 
    *  argument. 
    */ 

aber das ist nicht wahrscheinlich, was Sie im Sinn hatten.

+0

Die vorgeschlagene Funktionalität erfordert nicht mehr die Scala bereits hat. Es ist nur eine Syntax Zucker. – ayvango

+0

@ayvango Scala hat definitiv keine Unterstützung für statische Verifikation. Was meinst du und warum der Downvote? –

+0

Thema Starter brauchen keine statische Überprüfung. Er will nur die unapply-Methode mit den bereitgestellten Hinweisen erweitern. – ayvango

6

+1 für eine interessante spekulative Frage. Da Sie nicht auf der Typenebene arbeiten, können Sie die Instanziierung zur Kompilierzeit nicht überprüfen, außer vielleicht für sehr spezielle Prüfungen mit Makros, z. wenn Sie Literale an den Konstruktor übergeben.

Auf der anderen Seite ist Ihr Szenario, der Mustervergleich, eine Laufzeitaktion. Damit dies funktioniert, können Sie Extraktoren anstelle von Fallklassen verwenden.

case class Args(arg1: Int, arg2: Int) 
object ValidArgs1 { 
    def apply(arg1: Int, arg2: Int): Args = { 
    val res = Args(arg1, arg2) 
    require(unapply(res)) 
    res 
    } 
    def unapply(args: Args): Boolean = args.arg1 > 1 && args.arg2 < 10 
} 

def process(args: Args) = args match { 
    case ValidArgs1() => "ok" 
    case _   => "invalid" 
} 

process(ValidArgs1(2, 9)) 
process(Args(1, 10)) 
process(Args(3, 4)) 
+0

Dies ist perfekt danke, und Entschuldigung für die späte Antwort! – newlogic

+0

Eigentlich denke ich, es ist fast da, vielleicht könnten wir die Methoden apply und unapply in die Fallklasse einfügen und dann versiegeln, um uns Kompilierungszeitprüfungen zu geben, um sicherzustellen, dass wir einen Ausführungspfad für den Typ zuordnen, aber nur zusammenpassen und ausführen pathway, wenn die apply/unapply-Bedingung erfüllt ist? – newlogic

Verwandte Themen