Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why scala Map does not implement unapply?

Tags:

scala

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?

like image 548
David Portabella Avatar asked Dec 06 '16 15:12

David Portabella


People also ask

What is Unapply in Scala?

The unapply method breaks the arguments as specified and returns firstname object into an extractor . It returns a pair of strings if as an argument, the first name and last name is passed else returns none. Example : Scala.

How is map implemented in Scala?

Per the Scaladoc, “implements immutable maps using a list-based data structure.” As shown in the examples, elements that are added are prepended to the head of the list. Keys of the map are returned in sorted order. Therefore, all traversal methods (such as foreach) return keys in that order.

How do you add a value to a map in Scala?

Solution. Add elements to a mutable map by simply assigning them, or with the += method. Remove elements with -= or --= . Update elements by reassigning them.

Are maps mutable in Scala?

Maps are classified into two types: mutable and immutable. By default Scala uses immutable Map. In order to use mutable Map, we must import scala.


1 Answers

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.

like image 183
Rex Kerr Avatar answered Sep 29 '22 15:09

Rex Kerr