2011-11-15 30 views
3

斯卡拉2.8.1如何我摆脱“未因删除”的警告时,模式匹配

我一直在使用的解析器/组合子的QA来编写验收测试,实现了一个非常简单的外部DSL。

最近我加入循环的能力在一组表达式,像这样

sealed trait Expr 

... 
//insert other case classes extending 'Expr' here 
... 

case class Repetition(times: Int, expressions: List[Expr]) extends Expr 

class TestFixtureParser(....) extends RegexParsers { 
    val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ { 
    case (times: Int) ~ (exprs: List[Expr]) => { 
     Repetition(times, exprs) 
    } 
    } 

    private val expressions: Parser[List[Expr]] = (repeatParser | 
    /*insert other Parser[Expr]s '|' together here */ | verifyParser).* 

} 

建设的时候,我收到了警告warning: non variable type-argument ... is unchecked since it is eliminated by erasure时,模式匹配。我也尝试使用以下的解压缩。

//Doesn't build with error 
    /* 
    error: missing parameter type for expanded function ((x0$2) => x0$2 match { 
     case $tilde((times @ _), (exprs @ _)) => Repetition(times, exprs) 
    }) 
     r: ~[Int, List[Expr]] => { 
    */ 
    val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ { 
    r: ~[Int, List[Expr]] => { 
     case times ~ exprs => 
     Repetition(times, exprs) 
    } 
    } 

    //Actually this does build without warning. 
    //I am unfortunately using intelliJ and it doesn't like it 
    val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ { 
    repetitions: ~[Int, List[Expr]] => { 
     val ~(times, exprs) = repetitions 
     Repetition(times, exprs) 
    } 
    } 

    //Builds but same warning 
    val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ { 
    repetitions => { 
     val ~(times: Int, exprs: List[Expr]) = repetitions 
     Repetition(times, exprs) 
    } 
    } 

有没有人有没有这个警告在一个优雅的方式提取exprs有什么建议?它的功能是如此。我应该忽略它吗?我讨厌养成忽视警告的习惯。

编辑:答案。这实际上是我首先尝试的,但后来我添加了这些类型,因为intelliJ scala插件无法推断它们。

val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ { 
     case times ~ exprs => 
      Repetition(times, exprs) 
    } 
+1

我很好奇的是,为什么你的第一个“不构建”的例子不会构建......我认为Scala能够推断case表达式中的类型。你会得到什么错误? – Owen

回答

5

我觉得第一个“不建”的例子(它看起来像你返回的部分功能,而不是应用它,这是不是你想要的)你的语法是不正确的。尝试 写作:

val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ { 
    case times ~ exprs => 
     Repetition(times, exprs) 
} 

恐怕我不能对此进行测试,因为我没有你的代码的其余部分是 依赖,但这种结构的通常工作。

+0

啊,这是行不通的。 – drstevens

2

接受的答案是最好的,但这里是当不工作的替代品:

r: ~[t1, t2] => { 
    case times ~ exprs => 
    Repetition(times, exprs) 
} 

以上,t1t2推断,他们可能只是推断Any。不管他们被推断为什么,但是,这是你用这种语法可以做的最好的。

val ~(times: Int, exprs: List[t]) = repetitions 

在这里,因为您正在提取值,您可以实际检查类型。您没有测试是否有~[Int,List[Int]] - 您正在测试提取的值的类型是IntList[t]。请注意,您收到的警告来自List的类型参数。

+0

是的,我完全得到擦除的东西。我在代码和接受的答案之间唯一的区别是我有明确的类型。问题在于,我现在太依赖IntelliJ scala插件了。它用一条红色的波浪线表示抱怨,不能在那里推断〜的类型。编译器说不然。这对于帮助我学习过去8个月左右的语言非常好,但随着我使用更高级的构造,重构工具和上下文帮助开始停止工作。 – drstevens

+1

@drstevens我不确定我们在谈论同样的事情。当我编写'〜[t1,t2]'时我非常精确:这里使用小写字母表示编译器应该推断类型,并将它们分配给't1'和't2'。 –

+0

你说得对,我们不是在谈论同一件事。我不知道小写字母的类型参数在这里有意义。我需要更多地了解这一点。谢谢你的回复。 – drstevens