Как сопоставить шаблон с несколькими списками аргументов? - PullRequest
19 голосов
/ 27 мая 2011

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

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))

Но на самом деле это не сработало.

Ответы [ 3 ]

22 голосов
/ 27 мая 2011

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

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
9 голосов
/ 28 мая 2011

Просто, основываясь на ответе Рекса, вы можете не только сопоставлять шаблоны по первому блоку параметров, но и с таким поведением.

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

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

1 голос
/ 28 мая 2011

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

...