Как избавиться от предупреждения «не проверено из-за стирания» при сопоставлении с образцом - PullRequest
3 голосов
/ 16 ноября 2011

Скала 2.8.1

Я реализовал очень простой внешний 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)
  }

Ответы [ 2 ]

5 голосов
/ 16 ноября 2011

Я думаю, что ваш синтаксис неправильный для первого примера "не создает" (похоже, что вы возвращаете частичную функцию, а не применяете ее, а это не то, что вам нужно). Пытаться писание:

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

Боюсь, я не могу проверить это, потому что у меня нет остальной части вашего кода зависит, но этот тип конструкции обычно работает.

2 голосов
/ 16 ноября 2011

Принятый ответ является лучшим, но здесь есть альтернативы, когда это не работает:

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

Выше, t1 и t2 выведены иони могут быть просто выведены на Any.Однако к какому бы выводу они ни относились, это лучшее, что вы можете сделать с этим синтаксисом.

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

Здесь, поскольку вы извлекаете значения, вы можете на самом деле проверять типы.Вы не проверяете, есть ли у вас ~[Int,List[Int]] - вы проверяете, имеют ли извлеченные значения типы Int и List[t].Обратите внимание, что вы получили предупреждение от параметра типа List.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...