Объединение двух комбинаций в одном - PullRequest
5 голосов
/ 29 февраля 2012

Как можно объединить (в хорошем смысле) два матча Scala?

Сначала я должен проверить, является ли значение Option допустимым:

myOption match {
  case Some(op) =>
    doSomethingWith(op)
  case None =>
    handleTheError()

Затем, если операциябыл действителен, я хочу проверить другой шаблон:

Path(request.path) match {
  case "work" => {
    println("--Let's work--")

  }
  case "holiday" => {
    println("--Let's relax--")
  }
  case _ => {
    println("--Let's drink--")
  }
}

Я мог бы объединить их так:

myOption match {
  case Some(op) =>
    doSomethingWith(op)
    Path(request.path) match {
      case "work" => {
        println("--Let's work--")          
      }
      case "holiday" => {
        println("--Let's relax--")
      }
      case _ => {
        println("--Let's drink--")
      }
    }
  case None =>
    handleTheError()

Но, это чувствуется неряшливо.Есть ли лучший способ объединить их так или иначе.

Обновление

Извинения, я должен был объяснить лучше.Я на самом деле пытаюсь выяснить, существует ли известная схема упрощения (или исключения) этих структур управления.Например (представьте, что это правда):

x match {
 case a => {
   y match {
    case c => {}
    case d => {}
   }
 }
 case b => {}
}

равно

x -> y match {
  case a -> c => {}
  case a -> d => {}
  case b => {}
}

Я просто бродил, если кто-то уже определил некоторые шаблоны рефакторинга для потока управления, во многом как алгебра, где 2(x + y) = 2x + 2y

Ответы [ 2 ]

9 голосов
/ 29 февраля 2012

Вы можете сделать

myOption map { success } getOrElse handleTheError

или с scalaz,

myOption.cata(success, handleTheError)

, где success - это что-то вроде

def success(op: Whatever) = {
  doSomethingWith(op)
  Path(request.path) match {
    case "work"    => println("--Let's work--")
    case "holiday" => println("--Let's relax--")
    case _         => println("--Let's drink--")      
  }
}

Обновление

Ваш псевдокод

x -> y match {
  case a -> c => {}
  case a -> d => {}
  case b => {}
}

можно буквально перевести в scala как

(x, y) match {
  case (a, c) => {}
  case (a, d) => {}
  case (b, _) => {}
}

Выглядит хорошо (и это, вероятно, то, что вы хотели), если у внутреннего сопоставителя есть только несколько вариантов (c и d в данном случае), но это приводит к дублированию кода (повторение шаблона a).Итак, в общем, я бы предпочел map {} getOrElse {}, или разделение шаблонов на меньшие функции.Но я повторяю, в вашем случае это выглядит разумно.

3 голосов
/ 01 марта 2012

Если проверяемые (выражения, которым вы соответствуете) не зависят друг от друга, то есть вы можете вычислять их независимо, вы можете выполнить оба match одновременно, поместив проверяемых в кортеж.

Итак, ваш пример:

x match {
 case a => {
   y match {
    case c => fooC(...)
    case d => fooD(...)
   }
 }
 case b => fooB(...)
}

можно переписать в виде:

(x,y) match {
  case (a, c) => fooC(...)
  case (a, d) => fooD(...)
  case (b, _) => fooB(...)
}

..., если y не зависит от x.

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