Scala 2.8.1
I have implemented a very simple external DSL using parser/combinators for QA to write acceptance tests.
Recently I added the ability to loop over a set of expressions like so
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 ).*
}
When building, I receive the warning warning: non variable type-argument ... is unchecked since it is eliminated by erasure
when pattern matching. I have tried extracting using the following as well.
//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)
}
}
Does anyone have any suggestions for extracting exprs
in an elegant way without this warning? It does function as is. Should I just ignore it? I would hate to get into the habit of ignoring warnings.
Edit: Answer. This was actually what I tried first but then I added the types because the intelliJ scala plugin couldn't infer them.
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
case times ~ exprs =>
Repetition(times, exprs)
}
I think your syntax is not right for the first "doesn't build" example (it looks like you're returning a partial function rather than applying it, which isn't what you want). Try writing:
val repeatParser: Parser[Expr] = (l("repeat") ~> number) ~ (l("{") ~> expressions <~ l("}")) ^^ {
case times ~ exprs =>
Repetition(times, exprs)
}
I'm afraid I can't test this because I don't have the rest of your code it depends on, but this kind of construct usually works.