Подтвердить что ты не робот

Почему переменные не допускаются в альтернативных шаблонах?

Часто у вас есть "симметричные" совпадения и вы хотите писать такие вещи, как:

def g(p:(Int,Int)) = p match {
  case (10,n) | (n,10) => println(n)
  case _ => println("nope")
}

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

def g(p:(Int,Int)) = p match {
  case (10,n) => println(n)
  case (n,10) => println(n)
  case _ => println("nope")
}

Итак, почему у нас есть это ограничение?

4b9b3361

Ответ 1

Вероятно, потому что потребуется некоторое время для реализации, и это время лучше потрачено в другом месте. Это также излишне увеличивало бы сложность языка и его компилятора. Как вы уже упоминали, проблему можно легко избежать. Еще один способ избежать проблемы - написать пользовательский экстрактор:

object ThisOrThat {
  def unapply(p:(Int,Int)):Option[Int] = p match {
    case (10, n) => Some(n)
    case (n, 10) => Some(n)
    case _ => None
  }
}

Ответ 2

Похоже, было бы утомительно реализовывать... Там предложение функции назад.

Очевидными обходными решениями являются либо определение функции для результата, и вызов ее из отдельного case (лучше для простых паттернов), либо для определения пользовательского экстрактора для альтернативного шаблона, как предложил Ким (лучше, когда он вложенные внутри шаблона, который вам не нужно дублировать).

В любом случае, это заканчивается более подробным и трудным для чтения, чем если бы оно поддерживалось языком, но, надеюсь, кто-то его осуществит в конце концов.