2012-08-11 4 views
7

È possibile combinare condizioni di guardia con pattern matching all'interno di dichiarazioni di classi di case sigillate?Scala: è possibile combinare condizioni di guardia con corrispondenze di pattern in primo piano all'interno delle dichiarazioni della classe di case sigillate

Mi rendo conto che è possibile includere condizioni di guardia all'interno del blocco di corrispondenza, ma ritengo che sarebbe utile definire queste condizioni in anticipo nelle classi di casi sigillate. Ciò consentirebbe agli sviluppatori di definire una serie rigorosa di possibili input che il compilatore controllerebbe durante la corrispondenza del modello.

Quindi, in sintesi mi piacerebbe essere in grado di fare l'equivalente di qualcosa di simile:

// 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 
    } 
} 

risposta

-1

Non credo che si sarà in grado di avere generali vincoli/affermazioni che vengono controllati a compilare-tempo in Scala, perché Scala non ha uno static verifier che sarebbe necessario per fare questo. Se sei interessato, dai un'occhiata a (lingue) di ricerca/strumenti come ESC/Java, Spec#, Dafny o VeriFast.

Ci potrebbero essere modi di avere una quantità molto limitata di verifica statica con il regolare Scala compilatore utilizzando type-level programming o Scala macros, ma questo è solo un ipotesi di mio, come io non sono familiarità con nessuno dei due. Ad essere onesti, devo ammettere che sarei abbastanza sorpreso se i macro potessero effettivamente aiutare qui.

Ciò che funziona è il controllo dell'asserzione di runtime, ad es.

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. 
    */ 

ma questo probabilmente non è quello che avevate in mente.

+0

La funzionalità suggerita non richiede più la scala ha già. È solo uno zucchero sintassi. – ayvango

+0

@ayvango Scala sicuramente non ha supporto per la verifica statica. Cosa intendi e perché il downvote? –

+0

topic starter non necessita di verifica statica. Vuole solo un metodo unpply esteso con suggerimenti forniti. – ayvango

6

+1 per un'interessante domanda speculativa. Dato che non stai operando a livello di tipo, non puoi verificare l'istanziazione in fase di compilazione, tranne forse per controlli molto speciali con macro, ad es. quando passi letterali al costruttore.

D'altra parte, lo scenario, la corrispondenza del modello, è un'azione di runtime. Affinché funzioni, è possibile utilizzare gli estrattori anziché le classi dei casi.

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

Questo è perfetto grazie, e scusa per la risposta tardiva! – newlogic

+0

In realtà penso che ci sia quasi, forse potremmo costruire aggiungere i metodi apply e unpply nella classe case, quindi sigillarlo per darci un controllo del tempo di compilazione per assicurarci di mappare un percorso di esecuzione per il tipo, ma solo abbinare ed eseguire percorso se si verifica la condizione di applicazione/non richiesta? – newlogic

Problemi correlati