Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rules on using a case statement to destruct a tuple in Scala

Tags:

scala

I have the following code:

val xs = List(('a', 1), ('a', 2), ('b', 3), ('b', 4))

I want to transform this into a Map. e.g. Map('a' -> Seq(1,2), 'b' -> Seq(3,4)). So I proceed to write the transformation:

xs.groupBy(_._1) map {
  case (k, v) => (k, v.map(_._2))
}

Why does the brace after the map need to be a {. When I started, I assumed I could do the following:

xs.groupBy(_._1).map(case (k, v) => (k, v.map(_._2)))

But that doesn't compile.

like image 862
andyczerwonka Avatar asked Oct 30 '12 00:10

andyczerwonka


2 Answers

Because .map method accepts a function

What you've actually written is

map({
  case (k, v) => (k, v.map(_._2))
})

and the { case (k, v) => (k, v.map(_._2)) } is a shortcut definition for pattern matching anonymous function (SLS, §8.5) which is one of the function kinds:

val isOdd: PartialFunction[Int, String] = {
   case x if x % 2 == 1 => x+" is odd"
}

val upcastedIsOdd: Function[Int, String] = {
   case x if x % 2 == 1 => x+" is odd"
}

You cannot ommit curly braces (so you'll loose partial function and patten matching nicity) but you can skip plain braces (and still retain partial function) just like in the snippet below:

scala> List(1,2,3).take(1)
//res0: List[Int] = List(1)
scala> List(1,2,3) take 1
//res1: List[Int] = List(1)
like image 137
om-nom-nom Avatar answered Nov 13 '22 10:11

om-nom-nom


It seems the real question here is when can one use parenthesis ( in place of braces { to represent an anonymous function. I recommend having a look at Daniel Sobral's answer to the question: What is the formal difference in Scala between braces and parentheses, and when should they be used?

like image 21
Kipton Barros Avatar answered Nov 13 '22 09:11

Kipton Barros