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

Как сопоставить шаблон с несколькими списками аргументов?

Рассмотрим этот класс:

class DateTime(year: Int, month: Int, day: Int)(hour: Int, minute: Int, second: Int)

Как бы выглядел метод unapply, если бы я хотел бы сопоставлять что-то вроде:

dt match {
  case DateTime(2012, 12, 12)(12, _, _) => // December 12th 2012, 12 o'clock
  /* ... */
}

Я пробовал это:

def unapply(dt: DateTime) = 
  Some((dt.year, dt.month, dt.day),(dt.hour, dt.minute, dt.second))

Но это не работает.

4b9b3361

Ответ 1

Случайные классы соответствуют (и выполняют свои другие отличные действия) только по первому набору параметров:

scala> case class A(i: Int)(j: Int) { }
defined class A

scala> A(5)(4) match { case A(5) => "Hi" }
res14: java.lang.String = Hi

scala> A(5)(4) == A(5)(9)
res15: Boolean = true

Если это не класс case, вы можете определить, что unapply - это все, что вы хотите, поэтому оно действительно соответствует разработчику класса. По умолчанию, нет никакого доступа, поэтому вы можете сопоставлять только с типом.

Если вы хотите использовать отличные функции класса case, включая возможность сопоставления и выполнения равенства во всем, но с каким-то делением, вы можете вставлять классы case:

case class Time(hour: Int, minute: Int, second: Int) { }
case class Date(year: Int, month: Int, day: Int) { }
case class DateTime(date: Date, time: Time) { }

scala> val dt = DateTime(Date(2011,5,27), Time(15,21,50))
scala> dt match { case DateTime(Date(2011,_,_),Time(h,m,50)) => println(h + ":" + m) }
15:21

Ответ 2

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

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

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

Ответ 3

Вероятно, это не сработало, потому что Scala не имеет оператора запятой, и вы возвращаете Some((a,b),(x,y)) из экстрактора. Если вы использовали вместо Some(((a,b,c),(x,y,z))) (т.е. A Tuple2[Tuple3[A,B,C],Tuple3[X,Y,Z]], я думаю, что он, вероятно, сработает.