Is it possible to combine guard conditions with pattern matching within sealed case class declarations?
I realise its possible to include guard conditions within the match block but I feel it would be beneficial to define this conditions up front in the sealed case classes. This would allow developers to define strict set of possible inputs which the compiler would check when pattern matching.
So in summary I'd like to be able to do the equivalent of something like this:
// 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
}
}
+1 for an interesting speculative question. Since you are not operating at the type level, you cannot verify the instantiation at compile time, except maybe for very special checks with macros, e.g. when you are passing literals to the constructor.
On the other hand, your scenario, the pattern matching, is a runtime action. For that to work, you could use extractors instead of case classes.
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With