Как именно case работает с частичными функциями в Scala?

Я только начинаю свой, казалось бы, крутой период обучения работе с Scala и не совсем понимаю, как именно «case» работает в частичных функциях.

Я посмотрел на определение самой PartialFunction, и там я вижу пример, подобный следующему:

val isEven: PartialFunction[Int, String] = { 
   case x if x % 2 == 0 => x+" is even" 
}

Я застрял в case x if x% 2 - как Scala узнает, что здесь что? Каково формальное определение этого оператора / ключевого слова "case"?

Я думаю, что одна из причин моего замешательства заключается в том, что в Lift я вижу такие вещи (в классах Actor):

override def messageHandler = {
   case SomeKindOfUserMessageClass(id1, param1) => ....
   case AnotherKindOfUserMessageClass(id2) => ....
}

Я как бы интуитивно понимаю, что здесь происходит, но не могу составить какое-то единое определение того, как следует использовать «case». Еще больше меня озадачивает то, как компилятор Scala все это распутывает.


person Alex N.    schedule 24.11.2013    source источник
comment
В спец это 8.5. Для переопределения он знает тип функции. См., Например, stackoverflow.com/q/12869251/1296806 В противном случае, как говорится в ответах, это просто блок предложений case как обычное совпадение с образцом.   -  person som-snytt    schedule 24.11.2013


Ответы (4)


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

Во втором примере используются экстракторы. Оценка m match { case A(x) => } в Scala включает вызов A.unapply(m). Сопутствующий объект класса case является экстрактором (классы case используются чаще, чем собственно написание unapply метода).

Спецификация языка Scala трудна для чтения, но иногда стоит попробовать взглянуть на нее, особенно если вы ищете формализм. Глава 8 посвящена сопоставлению с образцом. В разделе 8.4 представлена ​​идея использования if в предложении case, как в вашем первом примере.

person Chris Martin    schedule 24.11.2013

В разделе «Последовательности регистров как частичные функции "на странице http://www.artima.com/pins1ed/case-classes-and-pattern-matching.html, я наткнулся на следующие предложения, которые, как мне кажется, также могут быть хорошим ответом на вопрос, «как следует использовать case».

A sequence of cases (i.e., alternatives) in curly braces can be used anywhere a function literal can be used. Essentially, a case sequence is a function literal, only more general. Вместо одной точки входа и списка параметров в последовательности случаев есть несколько точек входа, каждая со своим собственным списком параметров. Each case is an entry point to the function, and the parameters are specified with the pattern. The body of each entry point is the right-hand side of the case.

person shyan1    schedule 14.06.2014

Думайте о case как о сопоставлении некоторого условия или, более конкретно, о некотором шаблоне. Есть несколько способов указать узор.

case SomeKindOfUserMessageClass(id1, param1): здесь говорится, что значение должно быть типа SomeKindOfUserMessageClass, и если да, то уничтожить значения до id1 и param1. Это похоже на условие с сопоставлением с образцом.

case x if x % 2 == 0: здесь говорится, что условие состоит в том, что значение должно делиться на 2, и если да, то привязать значение к x ИЛИ вы можете сказать, привязать значение к x и проверить, делится ли оно на 2.

person Ankur    schedule 24.11.2013

Думайте об этом как об операторе switch на других языках.

В PHP вы должны использовать регистр перед каждой опцией. В рубине вы должны использовать слово «когда» ... и аналогичные слова в других языках.

Он работает сверху вниз и запускает код для первого совпадающего шаблона. Вы можете сопоставить на основе значения, типа, конструктора и т. Д., И он запускает только один блок кода ... и проверяет сверху вниз.

Это может быть в синтаксисе ...

val x = List(1,2,3,4)
x match {
  case Nil => Nil
  case x => x map someFunction
}

или вы также можете использовать сопоставление с образцом в лямбда-выражениях.

Ознакомьтесь с курсом «Принципы функционального программирования в scala» на сайте coursera.org. Если бы вы взяли это, у вас был бы хороший пирог в scala.

person Dante Romero    schedule 24.11.2013