Можно ли разложить операторы соответствия Scala с использованием частичных функций? - PullRequest
0 голосов
/ 27 октября 2019

У меня есть выражение соответствия, подобное этому:

    i match {
      case x if x == 0 ⇒
        romanNumeral

      case x if x >= 1000 ⇒
        this.roman(i - 1000, s"${romanNumeral}M")

      case x if x >= 900 ⇒
        this.roman(i - 900, s"${romanNumeral}CM")

      // etc.

В зависимости от того, как это отформатировано, это может быть около 30 строк избыточного кода. Поэтому мне интересно, возможно ли сделать этот код более сухим.

Поэтому я создал частичную функцию:

  private def toRoman(upperGuard: Int, token: String, romanNumeral: String): String = {
    case value: Int if value >= upperGuard ⇒
      this.roman(upperGuard - 1, s"$romanNumeral$token")
  }

, которую я затем попытался включить в приведенный выше механизм сопоставления, например:

    i match {
      case x if x == 0 ⇒
        romanNumeral

        toRoman(1000, "M", romanNumeral)
        toRoman(900, "CM", romanNumeral)
        // etc.

... Но это не сработает, потому что компилятор Scala не распознает эти функции как операторы case, которые он ищет.

Есть ли способ заставить эту работу работать

Ответы [ 3 ]

1 голос
/ 28 октября 2019

Вы можете создать ваши дела как частичные функции:

private def toRoman(upperGuard: Int, token: String, romanNumeral: String): PartialFunction[Int, String] = {
    case value if value >= upperGuard =>
      this.roman(upperGuard - 1, s"$romanNumeral$token")
}

val firstCase: PartialFunction[Int, String] = {
    case x if x == 0 => romanNumeral
}

И затем составить это так:

val toRomanPartialFunction = firstCase
  .orElse(toRoman(1000, "M", romanNumeral))
  .orElse(toRoman(900, "CM", romanNumeral))

После этого вы можете использовать его как обычную функцию:

toRomanPartialFunction.apply(443) 
toRomanPartialFunction(443) 
0 голосов
/ 28 октября 2019

У вас нет выражения соответствия шаблону, вы просто пишете оператор if else. Если вы хотите вернуть функцию, вы должны написать: x => this.something(x,"foo-bar") Вам не нужно case x. Если у вас есть только одно выражение в LHS case x, вам не нужно сопоставление с образцом, и вы можете просто использовать if else. Сопоставление с образцом без иерархии классов не имеет смысла.

0 голосов
/ 28 октября 2019

Таким образом, вы в основном хотите сделать код менее повторяющимся, обо всем по порядку:

  • Компилятор Scala не распознает эти функции как операторы case, потому что они являются функциями;
  • Во-вторых, эта функция на самом деле не является частичной функцией;
  • Наконец, эти совпадения могут быть такими, если вы найдете способ сокращения строк кода путем группировки в какую-то функцию, как вы это делалиотлично, но я не нахожу их избыточными, если только вы не можете переделать их с помощью функции, как я сказал.

Ps: эта функция не справляется с задачей

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