David Portabella
David Portabella

Reputation: 12720

why scala Map does not implement unapply?

I wrote the following use case in scala:

val wordShortcut = Map("volume" -> "vol", "report" -> "rpt", ...)

object WordShortcutCase {
  def unapply(key: String): Option[String] = wordShortcut.get(key)
}

val pluralR = "(.+)s".r

def encodeToken(token: String) = token match {
  case WordShortcutCase(short) => short
  case pluralR(singular) => singular
  case _ => token
}

if scala Map would implement unapply, I wouldn't need the extra WordShortcutCase object (i could use case wordShortcut(short) => short instead`). This seems a common pattern to me.

And so the question is why scala Map does not implement the unapply method?

Upvotes: 6

Views: 1064

Answers (1)

Rex Kerr
Rex Kerr

Reputation: 167891

Map doesn't implement unapply because there is no sensible implementation that has the same characteristics as other collections.

In particular, you seem to want apply and unapply to do basically the same thing. But that's not how other collections work; they bind variables to contents and expect that the list is exhaustive (in the absence of a binding to "the rest"):

val xs = List("fish")
val ys = List("fish", "dish")
def iam(zs: List[String]) = zs match {
  case List(x) => println(s"I am a $x")
  case _       => println("Who am I??")
}
iam(xs)  // Prints 'I am a fish'
iam(ys)  // Prints 'Who am I??'

If Map were not a collection it would be free to implement unapply as another way to do an apply, more like regex does (though there, note that the key feature is being able to bind multiple variables to parts of the regex match). But since it is, having a regex-like unapply would be highly confusing because of the difference from other collections; and because maps are unordered and unapplySeq is ordered, having the same unapply as other collections would also be confusing. So it just doesn't have one.

Upvotes: 2

Related Questions