2012-08-11 31 views
7

在密封案例类声明内是否可以结合警戒条件和模式匹配?斯卡拉:我们可以结合警戒条件和模式匹配密封案例类声明

我意识到在匹配块中可能包含警戒条件,但我觉得在密封的案例类中预先定义这个条件是有益的。 这将允许开发人员定义严格的可能输入集合,编译器将在模式匹配时检查这些输入。

因此,在总结我希望能够做的是这样的等价物:

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

我不相信你就可以有在检查一般限制/断言编译时间在斯卡拉,因为斯卡拉没有static verifier这将需要做到这一点。如果你有兴趣,看看(研究)语言/工具,如ESC/Java,Spec#,DafnyVeriFast

可能有方法通过使用type-level programmingScala macros与常规编译器Scala进行非常有限的静态检查,但这仅仅是我的猜测,因为我对它们都不熟悉。说实话,我必须承认,如果宏在这里能够真正起作用,我会感到很惊讶。

什么工作是运行时断言检查,例如,

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

但这可能不是你想到的。

+0

建议的功能不需要更多的Scala已经有了。它只是一个语法糖。 – ayvango 2012-08-13 18:46:46

+0

@ayvango Scala绝对不支持静态验证。你是什​​么意思,为什么downvote? – 2012-08-13 19:23:46

+0

主题启动器不需要静态验证。他只是希望通过提供的提示扩展无用的方法。 – ayvango 2012-08-13 19:37:55

6

对于一个有趣的推测性问题+1。由于您不是在类型级别上操作,因此无法在编译时验证实例化,但可能需要对宏进行非常特殊的检查(例如,当你将文字传递给构造函数时。

另一方面,您的场景模式匹配是一个运行时动作。为了这个工作,你可以使用提取器而不是案例类。

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

这是完美的谢谢,并且对于迟到的回复感到抱歉! – newlogic 2012-10-17 21:45:29

+0

实际上我认为它几乎在那里,也许我们可以建立在案例类中添加apply和unapply方法,然后封装它给我们编译时间检查,以确保我们映射类型的执行路径,但只匹配并执行如果适用/不适用条件满足,通路如何? – newlogic 2012-10-17 21:51:27