Reputation: 12720
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
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